Datenstrukturen und Algorithmen SS17 Tutoriumslösung - Übung 3 (Abgabe 17.05.2017) Prof.aa Dr. Ir. G. Woeginger T. Hartmann, D. Korzeniewski, B. Tauer Globalübungsaufgabe1 (Mergesort): Sortieren Sie das folgende Array mithilfe von Mergesort aus der Vorlesung. Geben Sie dazu das Array nach jeder Merge-Operation an. 12 7 3 42 97 5 7 Lösung: Die grau unterlegten Zeilen dienen nur zur Veranschaulichung, an welchen Stellen das Array aufgeteilt wird. Sie sind zur Lösung der Aufgabe nicht nötig. 12 7 3 42 97 5 7 12 7 3 42 97 5 7 12 7 3 42 97 5 7 12 7 3 42 97 5 7 7 12 3 42 97 5 7 7 12 3 42 97 5 7 7 12 3 42 97 5 7 3 7 12 42 97 5 7 3 7 12 42 97 5 7 3 7 12 42 97 5 7 3 7 12 42 5 97 7 3 7 12 42 5 7 97 3 5 7 7 12 42 97 1 Datenstrukturen und Algorithmen SS17 Tutoriumslösung - Übung 3 (Abgabe 17.05.2017) Globalübungsaufgabe2 (Heapsort): Sortieren Sie das folgende Array mithilfe von Heapsort aus der Vorlesung. Geben Sie dazu das Array nach jeder Swap-Operation an und geben Sie zum jeweils noch unsortierten Arraybereich zusätzlich die grafische Darstellung als Heap an. 7 8 9 42 1 12 Lösung: Schritt 0: 7 9 8 7 12 1 42 8 9 42 1 12 Schritt 1: 7 12 8 7 9 1 42 8 12 42 1 9 Schritt 2: 7 12 42 8 7 42 9 1 12 8 2 1 9 Datenstrukturen und Algorithmen SS17 Tutoriumslösung - Übung 3 (Abgabe 17.05.2017) Schritt 3: 42 12 7 42 9 1 8 7 12 8 1 9 Schritt 4: 42 12 8 42 9 1 7 8 12 7 1 9 Schritt 5: 9 12 8 1 7 9 8 12 7 1 42 Schritt 6: 12 9 8 1 7 12 8 9 7 1 42 12 42 Schritt 7: 1 9 8 7 1 8 9 7 3 Datenstrukturen und Algorithmen SS17 Tutoriumslösung - Übung 3 (Abgabe 17.05.2017) Schritt 8: 9 1 8 7 9 8 1 7 12 42 12 42 9 12 42 9 12 42 Schritt 9: 7 1 8 7 8 1 9 Schritt 10: 8 1 7 8 7 1 Schritt 11: 1 7 1 7 8 Schritt 12: 7 1 7 1 8 9 12 42 1 7 8 9 12 42 Schritt 13: 4 Datenstrukturen und Algorithmen SS17 Tutoriumslösung - Übung 3 (Abgabe 17.05.2017) Globalübungsaufgabe3 (Rekursiver Sortieralgorithmus): sort ( int [] A , int l , int r ) { if ( A [ l ] > A [ r ]) { vertausche ( A [ l ] , A [ r ]); } if ( l < r -1) { k := (r - l +1) div 3; mid1 := l + k ; mid2 := l +2 k ; sort (A , l , mid1 -1); sort (A , mid1 , mid2 -1); sort (A , mid2 , r ); merge (A , l , mid1 -1 , mid2 -1); merge (A , l , mid2 -1 , r ); } } a) Geben Sie die Rekursionsgleichung T (n) für den gegebenen Sortieralgorithmus an. Wie würden Sie die Komplexitätsklasse von T (n) bestimmen? Dabei verursacht ein Vergleich zwischen Array-Elementen eine Kosteneinheit. Die Funktion merge(int[] A, int l, int mid, int r) braucht Θ(l−r+1) viele Kosten, alle anderen Operationen sind “kostenlos”. b) Ist der vorgestellte Sortieralgorithmus stabil? Begründen Sie kurz. Falls nicht, ändern Sie den Algorithmus so ab, dass er stabil wird. 5 Datenstrukturen und Algorithmen SS17 Tutoriumslösung - Übung 3 (Abgabe 17.05.2017) c) Ist der vorgestellte Algorithmus ein korrekter Sortieralgorithmus? Falls nein, zeigen Sie die nicht Korrektheit anhand eines Beispiels; falls ja, zeigen Sie dir Korrektheit. Sie dürfen die Korrektheit der merge-Funktion verwenden, d.h. merge(int[] A, int l, int mid, int r) sortiert die Elemente des Arrays von Positionen l bis r korrekt, falls zuvor das Array von l bis mid und das Array von mid+1 bis r korrekt sortiert ist. Lösung: a) 1 2 T (n) = 3 · T n +Θ n + Θ(n) 3 3 1 =3·T n + Θ(n) 3 Dabei steht 3·T ( 31 n) für die Komplexität der Rekursionsaufrufe und Θ( 23 n)+Θ(n)+1 für die Komplexität der Vergleiche und der 2 merge. Zur Bestimmung der Komplexitätsklasse verwenden wir das Mastertheorem. . . . b) Der Suchalgorithmus sort ist nicht stabil, wie wir an folgendem Beispiel sehen: Im folgenden sollen die Elemente 1 und 1∗ den gleichen Wert 1 haben. 2 1∗ 1 Im ersten Schritt, ist die erste if-Bedingungen erfüllt, sodass 2 und 1 vertauscht werden. Es erfolgen keine weiteren Vertauschungen. Daher ist das Ergebnis des Algorithmus: 1 1∗ 2 Der Algorithmus ist damit nicht stabil, da 1 und 1∗ ihre relative Position vertauscht haben. Es reicht aus, nur im Basisfall, d.h. wenn sich nur zwei Elemente im zu sortierenden Bereich befinden, diese per vertauschen zu sortieren. Wird der Sortieralgorithmus entsprechen implementiert (siehe den folgenden sort2) kann ein Element nicht über eins mit gleichem Schlüssel hinweg vertauscht werden, der Algorithmus ist somit stabil. 6 Datenstrukturen und Algorithmen SS17 Tutoriumslösung - Übung 3 (Abgabe 17.05.2017) sort2 ( int [] A , int l , int r ) { if ( l < r -1) { k := (r - l +1) div 3; mid1 := l + k ; mid2 := l +2 k ; sort2 (A , l , mid1 -1); sort2 (A , mid1 , mid2 -1); sort2 (A , mid2 , r ); merge (A , l , mid1 -1 , mid2 -1); merge (A , l , mid2 -1 , r ); } else if ( A [ l ] > A [ r ]) { vertausche ( A [ l ] , A [ r ]); } } c) Wir zeigen die Korrektheit per Induktion über die Größe des zu sortierenden Bereichs n = r − l + 1. Induktionsanfang, r − l + 1 ≤ 2: Es wird A[l] und A[r] vertauscht, falls A[l] < A[r]. Somit wird korrekt sortiert. Induktionsvoraussetzung. Für ein n ∈ N, sortiert sort Arrays der Größe höchstens n korrekt. Induktionsschritt, (n − 1) n = r − l + 1. Aus der Induktionsvoraussetzung folgt, dass das Array jeweils in einschließlich den Grenzen von l bis mid1 − 1 (erster Bereich), von mid1 bis mid2 − 1 (zweiter Bereich), und von mid2 bis r (dritter Bereich) richtig sortiert sind. Somit sind die Vorraumsetzung für den ersten merge über den 1. und 2. Bereich erfüllt, und daraufhin sind die Elemente in einschließlich den Grenzen l bis mid2 − 1 richtig sortiert. Es folgt, dass die zwei Bereiche für den zweiten merge jeweils bereits sortiert sind. Demnach ist das Array nach dem zweiten merge von einschließlich l bis r richtig sortiert, also im gesamten Bereich. Globalübungsaufgabe4 (Beweis für Vorlesung): Beweisen Sie, dass ein Heap mit n Elementen d n2 e Blätter besitzt. Lösung: Die Elemente eines Heaps können wir aufteilen auf einen vollständig gefüllten Binärbaum der Höhe h und x ≥ 0 vielen Elementen der Ebene unter der letzten voll besetzen Ebene. Ein vollständig gefüllter Binärbaum der Höhe h hat 2h+1 − 1 Elemente. Somit ist die Anzahl der Elemente des Heaps n = 2h+1 − 1 + x. Wir unterscheiden ob x gerade ist oder nicht. Fall, x ist gerade. Dann hat der Heap 2h − x x + x = 2h + := b 2 2 viele Blätter. Es gilt lnm 2 h = 2h+1 − 1 + x 1 x x = 2h − + = 2h + = b, 2 2 2 2 x 2 da 2 und ganze Zahlen sind. Fall, x ist ungerade. Dann hat der Heap 2h − x+1 x 1 + x = 2h + − := b 2 2 2 viele Blätter. Es gilt lnm 2 = 2h+1 − 1 + x x 1 x 1 = 2h + − = 2h + − = b, 2 2 2 2 2 7 Datenstrukturen und Algorithmen SS17 Tutoriumslösung - Übung 3 (Abgabe 17.05.2017) da 2h und x2 − 21 ganze Zahlen sind. Also gilt die Aussage, dass ein Heap mit n Elementen d n2 e Blätter besitzt. 8