UA DI H.M. Burgsteiner 17.5.2002 Lösungsskizzen zur Prüfung (1) Prinzipiell gibt es einen Zusammenhang zwischen Rechenzeit und Speicherverbrauch eines Algorithmus: Um eine Speicherzelle zu beschreiben braucht ein Algorithmus eine bestimmte Zeit O(1). Daraus folgt auch, daß ein Algorithmus es z.B. in O(n) Zeit nicht schaffen kann Ω(n2 ) Speicher zu benutzen. Dementsprechend kann bei den folgenden Punkten argumentiert werden. (a) Richtig. Es ist möglich, daß ein Algorithmus in dieser Zeit O(n log n) Speicher bearbeitet. O(n log n) heißt ja auch, daß es weniger Speicher sein kann, also z.B. Θ(1). (b) Richtig. Es wird Θ(n2 ) Speicher benötigt, Ω(n log n) stellt jedoch nur eine untere Schranke für die Zeit dar. Das heißt, daß der Algorithmus durchaus Θ(n2 ) oder noch mehr Zeit brauchen kann. (c) Falsch. Durch den Speicherbedarf allein, kann keine Aussage über die maximale Zeit gegeben werden. Ein Algorithmus den eine Zeit von Ω(42n ) braucht, um eine essentielle Frage zu beantworten, könnte genauso gut nur O(1) Speicher verwenden, gleichzeitig kann ein Algorithmus mit einer Laufzeit von O(n3 ) eben diesen Speicher von Ω(n3 ) verarbeiten. (d) Falsch. Wie in den einleitenden Worten gesagt, kann der Algorithmus pro Zeiteinheit nur eine Speicherstelle verwenden, d.h. wenn er maximal O(n log n) Zeit braucht (obere Schranke!), dann kann er nicht in dieser Zeit mindesten Ω(n2 ) (untere Schranke!) Speicher verwenden. (2) (a) Richtig. Z.B. trifft dies auf alle Sortieralgorithmen zu, die wir in der Vorlesung kennengelernt haben: O(n log n) ∈ O(n2 ) ∈ O(n4 ). (b) Falsch. Die Interpolationssuche findet einen gesuchten Wert auch schon in O(1) Zeit, z.B. wenn die gesuchten Werte wirklich exakt der Annahme der linearen Verteilung entsprechen. (c) Falsch. Man muß sich nur einen nach rechts entarteten Baum mit ungerader Anzahl von Knoten vorstellen. Dessen symmetrische Reihenfolge hat nicht die Wurzel in der Mitte. (d) Richtig. Z.B. haben die folgenden zwei Bäume eine idente SR: (1) B ... Wurzel, A ... linker Sohn, C ... rechter Sohn. (2) A ... Wurzel, B ... rechter Sohn, C ... rechter Sohn von B. (e) Falsch. Wiederum hilft bei der Überlegung die Betrachtung eines entarteten Baumes. (3) Wenn man beachtet, daß man über das Feld A nichts weiß, außer das es nur positive, ganze Zahlen entält, ist dieses Problem z.B. ganz einfach mit folgendem Algorithmus zu lösen: (1) Sortiere das Feld A in aufsteigender Reihenfolge (z.B. HeapSort, wegen guter Laufzeit im worst case). (2) In einer Schleife für i von 1 bis n wird jeweils b = A[i] ∗ A[i] berechnet und dann wird b mittels Binärsuche im Feld A gesucht. Liefert die Binärsuche einen Index kann das Programm terminieren und T RU E liefern, ansonsten gibt es nach dem Ende der Schleife F ALSE zurück. Zeitanalyse: T (n) = HeapSort + Schleife über Multiplikation und BinSearch = = O(n · log n) + n · (O(1) + O(log n)) = = O(n · log n) + n · O(log n) = O(n · log n) Speicheranalyse: HeapSort sortiert in-place, braucht daher keinen zusätzlichen Speicher bis auf Hilfsvariablen: O(1). BinSearch hat ebenfalls konstanten Speicherbedarf. Man benötigt insgesamt lediglich Speicher für Hilfsvariablen. S(n)=O(1). Korrektheit: Die Korrektheit in diesem Fall ist offensichtlich: Das sortierte Feld wird für jedes A[i]2 zur Gänze durchsucht. BinSearch findet garantiert einen Index falls das Element in diesem Feld vorhanden ist. Sobald BinSearch einen gültigen Index zuückliefert, kann der Algorithmus abgebrochen und T RU E ausgegeben werden. Anderenfalls läuft die Schleife bis n durch und der Algorithmus liefert am Ende F ALSE. (4) Siehe Skriptum Seiten 96-101.