Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.
Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung Nächste Überarbeitung | Vorherige Überarbeitung | ||
faecher:informatik:oberstufe:algorithmen:sorting:mergesort:start [13.02.2025 07:20] – [Mergesort: Versuch 1] Frank Schiebel | faecher:informatik:oberstufe:algorithmen:sorting:mergesort:start [03.06.2025 07:09] (aktuell) – [Zentrale Teilaufgabe: Merge] Frank Schiebel | ||
---|---|---|---|
Zeile 22: | Zeile 22: | ||
===== Zentrale Teilaufgabe: | ===== Zentrale Teilaufgabe: | ||
- | Das Zusammenfügen der sortierten Teilarrays ist ein zentraler Bestandteil des Mergesort-Verfahrens, darum schauen | + | Bevor wir den gesamten Algorithmus betrachten, wollen |
+ | Wir schauen also an einem Beispiel nochmal etwas genauer, wie man diesen Vorgang verstehen und implementieren kann. | ||
- | Gegeben sind also zwei sortierte Teilarrays, die zu einem sortierten Array zusammengefügt werden sollen: | + | Gegeben sind zwei **sortierte** Teilarrays, die zu einem **sortierten** Array zusammengefügt werden sollen: |
{{ : | {{ : | ||
Zeile 56: | Zeile 57: | ||
++++ Hinweis 2: | | ++++ Hinweis 2: | | ||
<code java> | <code java> | ||
+ | |||
+ | merged = new String[a.length + b.length]; | ||
// Das sind die Indizes für die beiden Teilarrays | // Das sind die Indizes für die beiden Teilarrays | ||
// Beide beginnen bei 0 | // Beide beginnen bei 0 | ||
- | int i=0; | + | int ia = 0; // Zeiger auf das Element in Teilarray a |
- | int j=0; | + | int ib = 0; // Zeiger auf das Element in Teilarray b |
- | // k läuft von 0 bis merged-length-1 | + | |
+ | // im läuft von 0 bis merged-length-1 | ||
// bei jedem Durchlauf muss ein neues Element eingefügt werden - | // bei jedem Durchlauf muss ein neues Element eingefügt werden - | ||
// nur welches? | // nur welches? | ||
// Es müssen 4 Fälle unterschieden werden. Denke an die Länge der Arrays a und b! | // Es müssen 4 Fälle unterschieden werden. Denke an die Länge der Arrays a und b! | ||
- | for(int | + | for(int |
// Fall 1: | // Fall 1: | ||
Zeile 82: | Zeile 86: | ||
++++ Hinweis 3: | | ++++ Hinweis 3: | | ||
<code java> | <code java> | ||
+ | |||
+ | merged = new String[a.length + b.length]; | ||
// Das sind die Indizes für die beiden Teilarrays | // Das sind die Indizes für die beiden Teilarrays | ||
// Beide beginnen bei 0 | // Beide beginnen bei 0 | ||
- | int i=0; | + | int ia = 0; // Zeiger auf das Element in Teilarray a |
- | int j=0; | + | int ib = 0; // Zeiger auf das Element in Teilarray b |
- | // k läuft von 0 bis merged-length-1 | + | // im läuft von 0 bis merged-length-1 |
// bei jedem Durchlauf muss ein neues Element eingefügt werden - | // bei jedem Durchlauf muss ein neues Element eingefügt werden - | ||
// nur welches? | // nur welches? | ||
// Es müssen 4 Fälle unterschieden werden. Denke an die Länge der Arrays a und b! | // Es müssen 4 Fälle unterschieden werden. Denke an die Länge der Arrays a und b! | ||
- | for(int | + | for(int |
// Fall 1 und 2 müssen überprüfen, | // Fall 1 und 2 müssen überprüfen, | ||
Zeile 100: | Zeile 105: | ||
// Was muss dann geschehen? | // Was muss dann geschehen? | ||
- | // Fall 1: i ist außerhalb der Länge von a | + | // Fall 1: ia ist außerhalb der Länge von a |
- | if(i >= a.length) { | + | if(ia >= a.length) { |
- | // Fall 2: | + | // Fall 2: |
- | } else if(j >= b.length) { | + | } else if(ib >= b.length) { |
// Fall 3: | // Fall 3: | ||
Zeile 122: | Zeile 126: | ||
++++ Hinweis 4: | | ++++ Hinweis 4: | | ||
<code java> | <code java> | ||
- | int i=0; | + | merged |
- | int j=0; | + | |
- | for(int | + | int ia = 0; // Zeiger auf das Element in Teilarray a |
- | if(i >= a.length) { | + | int ib = 0; // Zeiger auf das Element in Teilarray b |
+ | |||
+ | for(int | ||
+ | if(ia >= a.length) { | ||
// Das Array a ist abgearbeitet, | // Das Array a ist abgearbeitet, | ||
// von b ohne weiteres nach merged übertragen werden, weil a und b | // von b ohne weiteres nach merged übertragen werden, weil a und b | ||
// ja sortiert sind! Der Index von b muss jeweils erhöht werden. | // ja sortiert sind! Der Index von b muss jeweils erhöht werden. | ||
- | merged[k] = b[j]; | + | merged[im] = b[ib]; |
- | | + | |
- | } else if(j >= b.length) { | + | } else if(ib >= b.length) { |
// Das Array b ist abgearbeitet, | // Das Array b ist abgearbeitet, | ||
// von b ohne weiteres nach merged übertragen werden, weil a und b | // von b ohne weiteres nach merged übertragen werden, weil a und b | ||
// ja sortiert sind! | // ja sortiert sind! | ||
- | merged[k] = a[i]; | + | merged[im] = a[ia]; |
- | | + | |
- | } else if(less(b[j], a[i])) { | + | } else if(less(b[ib], a[ia])) { |
// Was fehlt hier? | // Was fehlt hier? | ||
} else { | } else { | ||
Zeile 151: | Zeile 157: | ||
++++ Lösungsvorschlag | Wenn du auf den Lösungsvorschlag zurückgreifen musstest: Kommentiere den Lösungsvorschlag ausführlich, | ++++ Lösungsvorschlag | Wenn du auf den Lösungsvorschlag zurückgreifen musstest: Kommentiere den Lösungsvorschlag ausführlich, | ||
<code java> | <code java> | ||
- | int i=0; | + | merged = new String[a.length + b.length]; |
- | int j=0; | + | |
- | | + | int ia = 0; // Zeiger auf das Element in Teilarray a |
- | for(int | + | int ib = 0; // Zeiger auf das Element in Teilarray b |
- | if(i >= a.length) { | + | |
- | | + | // im zeigt auf das zu besetzende Element im gemergten Array merged |
- | } else if(j >= b.length) { | + | for(int |
- | | + | // a ist schon komplett in merged - kopiere die Elemente von b |
- | } else if(less(b[j], a[i])) { | + | if(ia >= a.length) { |
- | merged[k] = b[j++]; | + | |
- | } else { | + | ib++; |
- | merged[k] = a[i++]; | + | |
- | | + | |
+ | ia++; | ||
+ | | ||
+ | merged[im] = a[ia]; | ||
+ | ia++; | ||
+ | } else { // b[ib] ist kleiner - kopiere nach merged | ||
+ | merged[im] = b[ib]; | ||
+ | ib++; | ||
+ | | ||
} | } | ||
+ | |||
</ | </ | ||
Zeile 170: | Zeile 186: | ||
- | ---- | ||
- | {{: | ||
- | === (A2) === | ||
- | |||
- | Gib zunächst **getrennt** den Aufwand der Splitphase und der Mergephase in O-Notation an und begründe deine Aussage. Überlege dann, wie daraus abgeleitet der generelle Aufwand für den gesamten Mergesort-Algorithmus ist. | ||
- | ===== Mergesort: | + | ===== Mergesort: |
+ | Nachdem wir jetzt über eine funktionale Methode zum Zusammenfügen der Teilarrays verfügen, implementieren wir den gesamten Algorithmus, | ||
---- | ---- | ||
{{: | {{: | ||
- | === (A3) Naiver Mergesort === | + | === (A2) Naiver Mergesort: Implementation |
Implementiere unter Verwendung der oben implementierten // | Implementiere unter Verwendung der oben implementierten // | ||
Zeile 232: | Zeile 244: | ||
</ | </ | ||
++++ | ++++ | ||
+ | |||
+ | ---- | ||
+ | {{: | ||
+ | === (A3) Naiver Mergesort: Aufrufbaum === | ||
+ | |||
+ | **(A)** Der folgende Aufrufbaum stellt dar, wie das Array '' | ||
+ | |||
+ | * In welcher Reihenfolge finden die Aufrufe der Funktion '' | ||
+ | * An welchen Stellen im Baum wird ein merge-Vorgang ausgelöst? | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | ++++ Lösung | {{ : | ||
+ | |||
+ | **(B)** Gegeben ist der folgende String, der sortiert werden soll: '' | ||
+ | |||
+ | ---- | ||
+ | {{: | ||
+ | === (A4) === | ||
+ | |||
+ | Gib zunächst **getrennt** den Aufwand der Splitphase und der Mergephase in O-Notation an und begründe deine Aussage. Überlege dann, wie daraus abgeleitet der generelle Aufwand für den gesamten Mergesort-Algorithmus ist. | ||
+ | |||
===== Arrayerzeugung ist teuer ===== | ===== Arrayerzeugung ist teuer ===== | ||
Zeile 239: | Zeile 273: | ||
Wir befassen uns zunächst nochmal mit dem Merge-Vorgang und implementieren mit unseren Kenntnissen vom ersten Versuch die Methode | Wir befassen uns zunächst nochmal mit dem Merge-Vorgang und implementieren mit unseren Kenntnissen vom ersten Versuch die Methode | ||
+ | <code java> | ||
public void merge(String[] a, String[] speicher, int min, int mitte, int max) | public void merge(String[] a, String[] speicher, int min, int mitte, int max) | ||
- | | + | </ |
in der Klasse '' | in der Klasse '' | ||
---- | ---- | ||
{{: | {{: | ||
- | === (A4) === | + | === (A5) === |
* Vollziehe das Zusammenfügen der Arrays, das Erzeugen des Speicher-Arrays und die Bestimmung den Methodenparameter nach. | * Vollziehe das Zusammenfügen der Arrays, das Erzeugen des Speicher-Arrays und die Bestimmung den Methodenparameter nach. | ||
Zeile 278: | Zeile 313: | ||
---- | ---- | ||
{{: | {{: | ||
- | === (A5) === | + | === (A6) === |
Vervollständige die Implementierung, | Vervollständige die Implementierung, |