U NIVERSITÄT KONSTANZ L EHRSTUHL FÜR P RAKTISCHE I NFORMATIK Alexander Wolff Datenstrukturen und Algorithmen WS’02/03 Klausur 13. Februar 2003, 8:00 – 10:00 Uhr Aufgabe 1 (5 Punkte) Kreuzen Sie die korrekten Aussagen an: richtig 1080 ∈ O(α(n, n)) √ 3 n ∈ Ω(log n) n X 1 ∈ O(1) 2i i=0 n X n i=0 i ∈ Θ(2n ) O(n) ∩ Ω(n log n) = ∅ Aufgabe 2 (4 Punkte) Geben Sie zwei in der Vorlesung behandelte Sortierverfahren an, deren asymptotische WorstCase-Laufzeit sinkt, wenn die zu sortierenden Daten schon sortiert sind. 1) 2) Begründen Sie ihre Antwort jeweils kurz. 1 Aufgabe 3 (4 Punkte) Betrachten Sie folgende Java-Methode: void gibaus(java.util.LinkedList L) { for (int i = 0; i < L.size(); i++) System.out.print(L.get(i)+" "); System.out.println(); } Setzen Sie voraus, dass die Methode get der Klasse java.util.LinkedList folgendermaßen implementiert ist: Object get(int i) { int n = this.size(); if ( (i < 0) || (i >= n) ) throw new java.lang.IndexOutOfBoundsException(); ListItem curr = null; if (i < n / 2) { curr = this.head; while (i-- > 0) curr = curr.next; } else { curr = this.tail; while (++i < n) curr = curr.prev; } return curr.key; } wobei private class ListItem { ListItem next; ListItem prev; Object key; } 2 (a) Geben Sie eine asymptotisch scharfe Schranke für die Zahl Z(n) der Variablenzuweisungen an, die beim Aufruf von gibaus(L) mit einer Liste L der Länge n ausgeführt werden. (Z(n) zählt also, wie oft „=“ ausgeführt wird.) Z(n) ∈ Θ( ), denn (b) Geben Sie eine Implementierung von void gibaus(java.util.LinkedList L) in Java an, die asymptotisch schneller ist als die obige. void gibaus(java.util.LinkedList L) { } Aufgabe 4 (3 Punkte) Gegeben sei eine Folge von n Zahlen, wobei n sehr groß sei. Sei k < n/ log n. Wie kann man ohne vorheriges Sortieren in O(n) Zeit k kleinste Folgenelemente bestimmen? 3 Aufgabe 5 (5 Punkte) Betrachten Sie folgende rekursive Funktion: int f(int n) { if (n <= 2) return 1; return f(n-1) + f(n-2); } (a) Was berechnet diese Funktion? (b) Wie groß ist die Anzahl A(n) der Additionen, die beim Aufruf von f(n) ausgeführt werden? n 1 2 3 4 5 6 7 f(n) A(n) Allgemein gilt A(n) = , denn (c) Wie kann man die Funktion f rekursiv so implementieren, dass sie in Zeit linear in n läuft? Sie können dazu vor dem Aufruf von f Variable initialisieren, O(n) Speicherplatz „investieren“ und die Schnittstelle von f abändern. 4 Aufgabe 6 (4 Punkte) Schreiben Sie in Java einen Iterator, der zwei Listen vom Typ java.util.LinkedList nacheinander durchläuft. import java.util.LinkedList; public class TwoListIterator extends Iterator { private Iterator it1, it2; private boolean done1; public TwoListIterator(LinkedList list1, LinkedList list2) { } public Object next() { } public boolean hasNext() { } public void remove() { } } 5 Aufgabe 7 (4 Punkte) (a) Wenden Sie Hashing mit der Sondierfunktion g(k, i) = ( h(k) + 2i + i2 ) mod 11 für i, k ∈ N0 und der Hashfunktion h(k) = k mod 13 für k ∈ N0 beim Einfügen der Zahlen 20, 12, 30 in folgende Hashtabelle an: 0 1 1 2 3 4 5 17 6 7 8 9 10 8 (b) Was ist der Vorteil von doppeltem Hashing gegenüber Hashing mit linearem oder quadratischem Sondieren? Fassen Sie sich kurz. 6 Aufgabe 8 (3 Punkte) Geben Sie einen Algorithmus an, der für einen ungerichteten planaren Graphen G(V, E) in O(|V |) Zeit entscheidet, ob G einen aufspannenden Baum besitzt, und wenn ja, die Kanten eines solchen Baums ausgibt. Zur Erinnerung: Ein aufspannender Baum in einem Graphen G ist ein zusammenhängender Teilgraph von G, der ein Baum ist und alle Knoten von G enthält. Begründen Sie, warum Ihr Algorithmus die geforderte Laufzeit besitzt. Aufgabe 9 (3 Punkte) Was passiert, wenn man den Algorithmus von Bellman-Ford auf einem Digraphen D(V, A) mit Startknoten s ∈ V statt |V | − 1 Phasen |V | Phasen lang laufen lässt? Ist der Algorithmus dann noch korrekt? Begründen Sie Ihre Antwort. Zur Erinnerung: eine Phase des Algorithmus’ von Bellman-Ford besteht darin, dass für jede Kante einmal die Prozedur R ELAX aufgerufen wird. 7 Aufgabe 10 (3 Punkte) Gegeben sei eine Menge von n Intervallen I1 = [a1 , b1 ], . . . , In = [an , bn ]. Beschreiben Sie, wie man in O(k + n log n) Zeit alle Paare {i, j} mit Ii ∩ Ij 6= ∅ bestimmen kann, wobei k die Anzahl dieser Paare ist. Aufgabe 11 (3 Punkte) Gegeben sei ein vollständiger binärer Baum Bn mit n Knoten (also n = 2k − 1 für ein k ∈ N0 ), dessen Blätter nil-Zeigern entsprechen und dessen Kanten jeweils zum Kindknoten gerichtet seien. Wenn Sie nun von jedem Knoten v des Baums auf direktem Wege zu einem beliebigen Blatt im Teilbaum mit Wurzel v laufen – wie lange dauert das insgesamt? Mit anderen Worten: Sei K(n) die Anzahl der dabei überquerten Kanten in Abhängigkeit von n. Geben Sie eine asymptotisch scharfe Schranke für K(n) an und begründen Sie, warum diese korrekt ist. Tipp: Vielleicht hilft es Ihnen, wenn Sie für jeden Knoten v genau angeben, zu welchem Blatt der Weg von v führen soll. K(n) ∈ Θ( ), denn 8