Datenstrukturen und Algorithmen Beispiellösung zu Heimübungsblatt 7. Abbildung 1: Das Array A als Baum (vgl. Foliensatz 16, Folie 3)

Ähnliche Dokumente
8. A & D - Heapsort. Werden sehen, wie wir durch geschicktes Organsieren von Daten effiziente Algorithmen entwerfen können.

Algorithmen und Datenstrukturen Heapsort

Werden sehen, wie wir durch geschicktes Organsieren von Daten effiziente Algorithmen entwerfen können.

Algorithmen I. Tutorium 1-5. Sitzung. Dennis Felsing

Sortieren II / HeapSort Heaps

Kapitel 8 Fortgeschrittene Sortieralgorithmen

Übersicht. Datenstrukturen und Algorithmen. Übersicht. Heaps. Vorlesung 8: Heapsort (K6) Joost-Pieter Katoen. 7. Mai 2015

Heapsort / 1 A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8]

Algorithmen und Datenstrukturen

Algorithmen und Datenstrukturen

Beispiellösung zu den Übungen Datenstrukturen und Algorithmen SS 2008 Blatt 5

Datenstrukturen & Algorithmen

7. Sortieren Lernziele. 7. Sortieren

8.1.3 Operation Build-Max-Heap Operation zur Konstruktion eines Heaps Eingabe: Feld A[1..n], n = länge(a) BUILD-MAX-HEAP (A)

Technische Universität München

Suchen und Sortieren Sortieren. Heaps

Kap. 3 Sortieren. 7. VO DAP2 SS Mai Vorlesung am Do 7.5. entfällt wegen FVV um 14 Uhr HeapSort ff 3.1.

Definition Ein Heap (priority queue) ist eine abstrakte Datenstruktur mit folgenden Kennzeichen:

Algorithmen und Datenstrukturen II

Informatik II, SS 2018

Aufgabe 8. 1 Arbeitsweise illustrieren. 2 Korrektheitsbeweis führen. 3 Laufzeitanalyse durchführen.

Auswählen nach Rang (Selektion)

3. Musterlösung. Problem 1: Heapsort

14. Sortieren II Heapsort. Heapsort. [Max-]Heap 7. Heapsort, Quicksort, Mergesort. Binärer Baum mit folgenden Eigenschaften

2. Grundlagen. Beschreibung von Algorithmen durch Pseudocode. Korrektheit von Algorithmen durch Invarianten.

Grundlagen der Algorithmen und Datenstrukturen Kapitel 6

Grundzüge DS & Alg (WS14/15) Lösungsvorschlag zu Aufgabenblatt 3. Aufgabe 1. (a) nicht-heap (b) Heap 25. (c) Beinahe-Heap 9.

Grundzüge von Algorithmen und Datenstrukturen, WS 15/16: Lösungshinweise zum 13. Übungsblatt

Heapsort, Quicksort, Mergesort. 8. Sortieren II

Algorithmen und Datenstrukturen

Aufgabe 2 Konstruktion von Binärbäumen Tafelübung

Algorithmen und Datenstrukturen (für ET/IT)

Heapsort. 1. Erstelle aus dem gegebenen Array einen Max-Heap (DownHeap) 2. Tausche erstes und letztes Element des Arrays

Lösungsvorschlag Hausübung 8

8. Sortieren II. 8.1 Heapsort. Heapsort. [Max-]Heap 6. Heapsort, Quicksort, Mergesort. Binärer Baum mit folgenden Eigenschaften

Heapsort, Quicksort, Mergesort. 8. Sortieren II

Algorithmen und Programmieren II

Algorithmen und Datenstrukturen

Kap. 3: Sortieren (3)

Gliederung. 5. Compiler. 6. Sortieren und Suchen. 7. Graphen

Alle bislang betrachteten Sortieralgorithmen hatten (worst-case) Laufzeit Ω(nlog(n)).

Informatik II, SS 2016

Termine für Übungstests. Kap. 3 Sortieren HeapSort ff Priority Queues. Motivation. Überblick. Analyse SiftDown

9. Rekursion. 1 falls n 1 n (n 1)!, andernfalls. Experiment: Die Türme von Hanoi. Links Mitte Rechts. Mathematische Rekursion

Kurs 1663 Datenstrukturen" Musterlösungen zur Klausur vom Seite 1. Musterlösungen zur Hauptklausur Kurs 1663 Datenstrukturen 15.

5. Vorrangwarteschlangen (priority queues)

lim log 2n n = > 0 Da es einen Limes gibt, gibt es auch einen Limes inferior, der gleich diesem Limes ist.

Programm heute. Algorithmen und Datenstrukturen (für ET/IT) Suchen. Lineare Suche. Such-Algorithmen. Sommersemester Dr.

Das Suchproblem 4. Suchen Das Auswahlproblem Suche in Array

Das Suchproblem. Gegeben Menge von Datensätzen. Beispiele Telefonverzeichnis, Wörterbuch, Symboltabelle

Das Suchproblem. Gegeben Menge von Datensätzen. Beispiele Telefonverzeichnis, Wörterbuch, Symboltabelle

Das Suchproblem 4. Suchen Das Auswahlproblem Suche in Array

6 Quicksort. die mittlere Laufzeit Θ(n log n) beträgt und. die in der asymptotischen Notation verborgenen Konstanten sehr klein sind.

5.5 Prioritätswarteschlangen

Vorlesung Datenstrukturen

Copyright, Page 1 of 7 Heapsort

21. Greedy Algorithmen. Aktivitätenauswahl, Fractional Knapsack Problem, Huffman Coding Cormen et al, Kap. 16.1, 16.3

Algorithmen und Datenstrukturen

Übung Algorithmen und Datenstrukturen

Heapsort. Ziel: Sortieren Feld A[1..n]von nschlüsseln in O(n log n)worst case Zeit(so wie Mergesort), aber ohne Zusatzspeicher(so wie Quicksort).

18. Natürliche Suchbäume

Praktikum Algorithmische Anwendungen WS 2006/07 Sortieren in linearer Laufzeit

Algorithmen I. Prof. Jörn Müller-Quade Institut für Theoretische Informatik Web:

9. Natürliche Suchbäume

Vorlesung Datenstrukturen

Algorithmen und Datenstrukturen 2

2. Klausur zur Vorlesung Algorithmentechnik Wintersemester 2006/ April 2007

Übung zu Algorithmen und Datenstrukturen (für ET/IT)

A7.1 Untere Schranke. Algorithmen und Datenstrukturen. A7.1 Untere Schranke. Algorithmen und Datenstrukturen. A7.2 Quicksort. A7.

Musterlösungen zu Datenstrukturen und Algorithmen SS 2005 Blatt 2, Aufgabe 3 Wir schreiben zunächst alle Funktionen zur Basis 2.

14. Rot-Schwarz-Bäume

Algorithmen und Datenstrukturen

Kürzeste (billigste) Wege

5. Vorrangwarteschlangen - Priority Queues

1. Teilklausur. Name:... Vorname:... Matrikel-Nummer:...

Beispiellösungen zu den Übungen Datenstrukturen und Algorithmen SS 2008 Blatt 6

9 Minimum Spanning Trees

Schleifeninvarianten. Dezimal zu Binär

21. Dynamic Programming III

Informatik II, SS 2014

Abschnitt: Algorithmendesign und Laufzeitanalyse

Algorithmen und Datenstrukturen

Binäre Suchbäume. Mengen, Funktionalität, Binäre Suchbäume, Heaps, Treaps

Klausur Algorithmen und Datenstrukturen

Suchen und Sortieren Sortieren. Heaps

INSERTION-SORT: Ja, Es wird immer das erste, kleinste Element an die neue Liste angehängt.

Vorlesung Informatik 2 Algorithmen und Datenstrukturen

24. Minimale Spannbäume

Algorithmen und Komplexität Lösungsvorschlag zu Übungsblatt 8

Algorithmen und Datenstrukturen

Algorithmen und Datenstrukturen SoSe 2008 in Trier. Henning Fernau Universität Trier

Heapsort. Erstellung eines Heaps

Heapsort. 1. Erstelle aus dem gegebenen Array einen Heap (DownHeap) 2. Tausche erstes und letztes Element des Arrays

Untere Schranke für allgemeine Sortierverfahren

EINI LW. Einführung in die Informatik für Naturwissenschaftler und Ingenieure. Vorlesung 2 SWS WS 11/12

Effiziente Algorithmen und Datenstrukturen I Kapitel 2: Priority Queues

Informatik II, SS 2014

Transkript:

Aufgabe 3 a) Wir verwenden zur Lösung den Algorithmus Build-Heap 1, dieser verwendet die Funktion Heapify. Unser Array A ist gegeben durch [7, 10,, 5, 5,, 3, 3, 17]. 10 5 5 3 17 7 Abbildung 1: Das Array A als Baum (vgl. Foliensatz 16, Folie 3) In Heapify wird nach Aufruf mit dem Array A die Variable heap-size auf 9 gesetzt. Unsere for-schleife läuft also von 9 = 4 bis 1. i=4 Aufruf von Heapify(A,4) i = 4 A[i] = 5 l = left(i) = i = A[l] = 3 r = right(i) = i + 1 = 9 A[r] = 17 In Zeilen 3 und 4 von Heapify wird der Index des größeren Werts von A[l] und A[i] bestimmt und in der Variable largest gespeichert, wenn l heap-size[a] gilt. Das ist hier der Fall, also bekommt largest den Wert von l = zugewiesen. Es gilt A[largest] = 3. In Zeile 5 von Heapify wird der Wert von A[largest] mit dem Wert A[r] verglichen, wenn r heap-size[a] gilt. Diese Bedingung ist erfüllt, A[largest] ist aber größer als A[r], also bleibt der Wert von der Variable largest unverändert. Die Bedingung in Zeile 6 ist erfüllt, deshalb werden die Werte von A[i] und A[largest] vertauscht. Der resultierende Baum ist: 1 siehe Foliensatz 16, Folie 36 siehe Foliensatz 16, Folie 14ff.

10 3 5 5 17 7 Nachdem die Werte vertauscht wurden, wird Heapify(A,) aufgerufen. Aufruf von Heapify(A,) i = A[i] = 5 l = left(i) = i = 16 r = right(i) = i + 1 = 17 In Zeilen 3 und 4 wird largest auf den Wert i = gesetzt, da l > heap-size[a] gilt. In Zeile 5 wird keine Änderung an der Variable largest vorgenommen, da r > heap-size[a] ist. Jetzt gilt i = largest und somit wird der Aufruf von Heapify(A,) ohne Änderungen oder weiteren Aufrufen von Heapify beendet. i=3 Aufruf von Heapify(A,3) i = 3 A[i] = l = left(i) = i = 6 A[l] = r = right(i) = i + 1 = 7 A[r] = 3 Das Element A[i] ist größer als seine beiden Kinder A[l] und A[r], also ist largest = i und es werden keine Änderungen und auch kein weiterer Aufruf von Heapify vorgenommen. i= Aufruf von Heapify(A,) i = A[i] = 10 l = left(i) = i = 4 A[l] = 5 r = right(i) = i + 1 = 5 A[r] = 5 Es gilt l heap-size[a] A[l] A[i] Also wird in Zeilen 3 und 4 largest = i = gesetzt. Weiterhin gilt r heap-size[a] A[r] > A[largest] Also wird in Zeile 5 largest = r = 5 gesetzt. Da largest i ist wird A[i] mit A[largest] vertauscht und Heapify(A,5) aufgerufen.

Aufruf von Heapify(A,5) 5 3 10 5 17 7 i = 5 A[i] = 10 l = left(i) = i = 10 r = right(i) = i + 1 = 11 In Zeilen 3 und 4 wird largest auf den Wert i = 5 gesetzt, da l > heap-size[a] gilt. In Zeile 5 wird keine Änderung an der Variable largest vorgenommen, da r > heap-size[a] ist. Jetzt gilt i = largest und somit wird der Aufruf von Heapify(A,5) ohne Änderungen oder weiteren Aufrufen von Heapify beendet. i=1 Aufruf von Heapify(A,1) i = 1 A[i] = 7 l = left(i) = i = A[l] = 5 r = right(i) = i + 1 = 3 A[r] = Es gilt l heap-size[a] A[l] > A[i] Also wird largest = l = gesetzt. Weiterhin gilt r heap-size[a] A[r] A[largest] Der Wert der Variable largest wird also nicht verändert. Da largest i ist wird A[i] mit A[largest] vertauscht und Heapify(A,) aufgerufen. 7 3 10 5 17 5

Aufruf von Heapify(A,) i = A[i] = 7 l = left(i) = i = 4 A[l] = 3 r = right(i) = i + 1 = 5 A[r] = 10 Es gilt l heap-size[a] A[l] > A[i] Also wird largest = l = 4 gesetzt. Weiterhin gilt r heap-size[a] A[r] A[largest] Der Wert der Variable largest wird also nicht verändert. Da largest i ist wird A[i] mit A[largest] vertauscht und Heapify(A,4) aufgerufen. Aufruf von Heapify(A,4) 3 7 10 5 17 5 i = 4 A[i] = 7 l = left(i) = i = A[l] = 5 r = right(i) = i + 1 = 9 A[r] = 17 Es gilt l heap-size[a] A[l] A[i] Also wird largest = i = 4 gesetzt. Weiterhin gilt r heap-size[a] A[r] > A[largest] Der Wert der Variable largest wird also auf r = 9 gesetzt. Da largest i ist wird A[i] mit A[largest] vertauscht und Heapify(A,9) aufgerufen. 17 5 7 3 5 10

Aufruf von Heapify(A,9) i = 9 A[i] = 5 l = left(i) = i = 1 r = right(i) = i + 1 = 19 In Zeilen 3 und 4 wird largest auf den Wert i = 9 gesetzt, da l > heap-size[a] gilt. In Zeile 5 wird keine Änderung an der Variable largest vorgenommen, da r > heap-size[a] ist. Jetzt gilt i = largest und somit wird der Aufruf von Heapify(A,9) ohne Änderungen oder weiteren Aufrufen von Heapify beendet. Nach diesem Durchlauf ist Build-Heap fertig. Der entstehende Heap ist in Abbildung zu sehen, es gilt: A = [5, 3,, 17, 10,, 3, 4, 5]. b) Sei A ein max-heap. Das bedeutet, dass in A die max-heap-eigenschaft gilt: Für jeden Knoten i außer der Wurzel gilt A[P arent(i)] A[i]. Sei i der Index einer Wurzel eines Teilbaumes. Sei i ein Kind von i und sei weiterhin A[i ] > A[i ]. Das wäre aber eine Verletzung der max-heap-eigenschaft, es gilt jetzt nämlich nicht mehr für alle Knoten, dass A[P arent(i)] A[i] gilt. Das ist ein Widerspruch zur Annahme, dass A ein max-heap ist.

Aufgabe 4 a) Diese Aussage ist richtig. Beweis: Ein Array A ist aufsteigend sortiert genau dann, wenn gilt: A[i] A[i + 1] 1 i < n (1) Ein Array A erfüllt die min-heap-eigenschaft genau dann, wenn gilt: A[P arent(i)] A[i] Benutzt man left(x) und right(x) und setzt die entsprechenden Definitionen ein, so erhält man folgende Schreibweise der min-heap-eigenschaft: A[i] A[left(i)] A[i] A[i] () A[i] A[right(i)] A[i] A[i + 1] (3) Wir wollen nun zeigen, dass ein Array, dass aufsteigend sortiert ist auch die min-heap- Eigenschaft erfüllt: Array aufsteigend sortiert Array erfüllt min-heap-eigenschaft Aus A[i] A[i + 1] folgt sofort, dass A[i] A[i] und A[i] A[i + 1] auch gelten. b) Diese Aussage ist falsch. Gegenbeispiel: 1 3 5 4 Dies ist offensichtlich ein min-heap, für jeden Knoten i außer der Wurzel gilt A[P arent(i)] A[i]. Betrachtet man das Array A = [1, 3,, 5, 4], so sieht man, dass es nicht aufsteigend sortiert ist. Damit wurde die Aussage widerlegt.

Aufgabe 5 1 function k k l e i n s t e Elemente (A, k ) // Erzeuge Array mit k Elementen, d i e s e s Array 3 // wird a l s max heap g e p f l e g t 4 B = new array [ 1,.., k ] 5 for i 1 to k do 6 B[i] 7 end for 9 for i 1 to n do 10 i f A[i] < B[1] then 11 B[1] A[i] 1 // s t e l l e max Heap E i g e n s c h a f t wieder her 13 Heapify(B, 1) 14 end i f 15 end for 16 17 // s o r t i e r e B a u f s t e i g e n d 1 MergeSort(B, 1, k) 19 0 return B 1 end Laufzeit Analyse: Die Zeilen 4 und 5-7 können in Laufzeit O(k) ausgeführt werden. Der Aufruf Heapify(B,1) benötigt Zeit O(log k), die Funktion wird im worst-case n mal aufgerufen. Für Zeilen 9-15 ergibt sich also eine Laufzeit von O(n log k). Der Aufruf von MergeSort benötigt Zeit O(k log k) da hier k Elemente sortiert werden sollen. Da n k gilt, hat der Algorithmus k-kleinste-elemente Laufzeit O(n log k).

Aufgabe 6 a) Die rot markierten Elemente wurden bereits durch den Algorithmus bearbeitet, die unterstrichenen Werte für i beziehen sich auf die Werte innerhalb der Funktion Max-Heap- Insert. i= Max-Heap-Insert(A, A[]) i= 10 5 5 3 17 7 Parent() = = 1 i = > 1 A[1] < A[] Also müssen die Elemente A[1] und A[] vertauscht werden, i wird auf Parent() gesetzt, also i = 1. 7 5 5 3 17 10 i=1 i ist jetzt 1, die while-schleife wird nicht weiter ausgeführt. i=3 Max-Heap-Insert(A, A[3]) i=3 7 5 5 3 17 Parent(3) = 10 3 = 1 i = 3 > 1 A[1] A[3]

Die Schleife wird also nicht betreten. i=4 Max-Heap-Insert(A, A[4]) 7 5 5 3 17 10 i=4 Parent(4) = 4 = i = 4 > 1 A[] A[4] Die Schleife wird also nicht betreten. i=5 Max-Heap-Insert(A, A[5]) 7 5 5 3 17 10 i=5 Parent(5) = 5 = i = 5 > 1 A[] < A[5] Also müssen die Elemente A[] und A[5] vertauscht werden, i wird auf Parent(5) gesetzt, also i =. 10 5 5 7 3 17

i= Parent() = = 1 i = > 1 A[1] < A[] Also müssen die Elemente A[1] und A[] vertauscht werden, i wird auf Parent() gesetzt, also i = 1. 5 10 5 7 3 17 i=1 i ist jetzt 1, die while-schleife wird nicht weiter ausgeführt. i=6 Max-Heap-Insert(A, A[6]) 5 10 5 7 3 17 i=6 Parent(6) = 6 = 3 i = 6 > 1 A[3] A[6] Die Schleife wird also nicht betreten. 5 10 5 7 3 17

i=7 Max-Heap-Insert(A, A[7]) i=7 Parent(7) = Die Schleife wird also nicht betreten. 7 = 3 i = 7 > 1 A[3] A[7] i= Max-Heap-Insert(A, A[]) i= 5 10 5 7 3 17 Parent() = = 4 i = > 1 A[4] < A[] Also müssen die Elemente A[4] und A[] vertauscht werden, i wird auf Parent() gesetzt, also i = 4. i=4 5 10 3 7 5 17 Parent(4) = 4 = i = 4 > 1 A[] < A[4] Also müssen die Elemente A[] und A[4] vertauscht werden, i wird auf Parent(4) gesetzt, also i =. 5 3 10 7 5 17

i= Parent() = = 1 i = > 1 A[1] A[] Die Schleife wird also nicht betreten. i=9 Max-Heap-Insert(A, A[9]) i=9 5 3 10 7 5 17 Parent(9) = 9 = 4 i = 9 > 1 A[4] < A[9] Also müssen die Elemente A[4] und A[9] vertauscht werden, i wird auf Parent(9) gesetzt, also i = 4. i=4 5 3 17 7 5 10 Parent(4) = 4 = i = 4 > 1 A[] A[4] Die Schleife wird also nicht betreten. 5 3 17 7 5 10

b) Die beiden Algorithmen erzeugen unterschiedliche Heaps, das Gegenbeispiel wurde in Aufgaben 3.a und 6.a geliefert. c) Korrektheit von Max-Heap-Insert Invariante Vor dem Durchlauf der while-schleife mit Index i erfüllt der Teilbaum mit Wurzel A[i] die max-heap-eigenschaft bis auf eine Mögliche Verletzung: A[i] kann größer sein als A[P arent(i)]. Initialisierung Vor dem ersten Schleifendurchlauf wurde nur der Wert von A[i] geändert und von daher kann nur dieses Element die max-heap-eigenschaft verletzen. Erhaltung In der while-schleife wird eine eventuelle auftretende Verletzung der maxheap-eigenschaft in der Zeile 5 behoben. Jetzt gilt die max-heap-eigenschaft im Teilbaum mit Wurzel A[i]. Durch die Vertauschung kann nur die max-heap-eigenschaft zwischen i und P arent(i) verletzt werden. Terminierung Erreicht der Algorithmus die Wurzel des Heaps (i = 1), so terminiert er und das gesamte Array erfüllt die max-heap-eigenschaft. Korrektheit von Build-Max-Heap Invariante Vor dem Durchlauf der Schleife mit Index i ist das Array A[1,.., i 1] ein max-heap Initialisierung Der erste Durchlauf erfolgt mit i =. Das Array A[1,.., 1] ist ein maxheap Erhaltung Vor Durchlauf mit Index i gilt die Invariante. Es wird dann Max-Heap- Insert(A, A[i]) aufgerufen. Durch diesen Aufruf wird der Heap korrekt um den Wert A[i] ergänzt. Die Korrektheit folgt aus der Korrektheit von Max-Heap-Insert. Terminierung Vor Durchlauf mit Index i = length(a) + 1 ist A[1,.., length(a)] ein max-heap. Laufzeit Die Funktion Build-Max-Heap (A) ruft in der for-schleife n 1 mal den Algorithmus Max-Heap-Insert auf. In diesem Algorithmus wird in der while-schleife im worst-case der Baum von einem Blatt zur Wurzel durchlaufen. Da es sich hier im weitesten Sinne

um einen vollständigen Binärbaum handelt ist die Höhe des Baums log n. Wir haben also insgesamt eine Laufzeit von n }{{ 1 } O(log n) }{{} = O(n log n) Aufrufe von Max-Heap-Insert Laufzeit von Max-Heap-Insert