versuche Merge Sort zu verstehen Informatik?

3 Antworten

Willst Du Mergesort verstehen oder willst Du diese Implementierung verstehen?

Mergesort an sich ist super simpel.

Eine Folge von einem Element ist sortiert. Eine leere Folge auch.

Wenn Du eine längere Folge hast, dann halbiere sie und mache mit jeder halben Folge Mergesort. Danach vereinige beide sortierten Folgen. Du vereinigst (mergest) sie, dadurch, dass Du jeweils das erste Element beider Folgen ansiehst und das größere Element entnimmst und an die sortierte Folge anhängst. Das machst Du so lange, bis beide Folgen leer sind. Das Resultat ist eine lange sortierte Folge.

EasternPremise 
Fragesteller
 01.06.2023, 09:44

jo also den algorithmus verstehe ich auch und hab auch einen umgesetzt, aber diesen da oben verstehe ich nur so halb, wieso wird dann bei der 2. forschleife das umgekehrt reingespeichert?

0
Hier werden ja die Werte in umgekehrter Reihenfolge ins hilfsarray b gespeichert, aber weiso ist das notwendig,

Vermutlich, weil sonst irgendwas überschrieben werden würde. Generell ein nicht einfach zu verstehender Algorithmus. Ich würde erst versuchen, ihn anhand eines Videos zu verstehen. Sich den Code zu merken und Zeile für Zeile zu verstehen ist schon nicht ohne.

EasternPremise 
Fragesteller
 31.05.2023, 22:21

ok vielen dank, dachte schon ich würde nur son Knoten im Kopf haben, ich hab den merge sort algorithmus uach anders implementiert aber mit viel mehr zeilen und 2 zusätzlichen arrays in denen ich immer die hälften speichere, funktoinerit auch ist aber eben sclhechter als der da oben, aber der da oben ist auch etwas komplizierter

0
        for (k = left; k <= mid; k++)
            b[k] = array[k];

Kopiert das linke zu mergende Teilarray 1:1 nach b.

        for (k = mid; k < right; k++)
            b[right + mid - k] = array[k + 1];

Kopiert das rechte Teilarray in umgekehrter Reihenfolge nach b.

Es sei left=10, right=20 und mid=30/2=15

left               mid               right
  10 11 12 13 14   15    16 17 18 19 20

Für den rechten Teil gilt:

for (k=15; k<20; k++):
k=15: b[20+15-15] = array [15+1] 20 -> 16
k=16: b[20+15-16] = array [16+1] 19 -> 17
.....

Beim Merge sollen die beiden sortierten Teilarrays sortiert zusammengeführt werden, ich muß also schauen, in welchem Teilarray das nächstgrößere Element zu finden ist.

In der Regel wird aber ein Teilarray bereits konsumiert sein, während im anderen noch Elemente sind. Das müßte ich gesondert prüfen. Um mir genau dies zu ersparen, wird der rechte Teil umgedreht und stattdessen von rechts genommen, denn so lässt sich die Schleife einfacher formulieren.

EasternPremise 
Fragesteller
 01.06.2023, 09:49

kannst du kurz erklären was du mit "in der regel wird aber ein teilarray bereits konsumiert sein"

0
KarlRanseierIII  01.06.2023, 14:05
@EasternPremise

Schau Di ram besten einen Grenzfall an wie:

1 2 3 | 4 5 6 #oder
4 5 6 | 1 2 3 # <- hierrüber sprchen wir jetzt

Ich schaue z.B. 4<=1 ? Nei, 1 nehmen ... und wenn ich die 3 entnommen habe, ist das rechte Teilarray leer. Ich habe also nichts mehr zum Vergleichen und muß das linke Teilaray kopieren, dazu brauchts nen Bounds-Check, damit ich merke, daß ich am Ende angekommen bin.

Jetzt mit Umkehrung:

4 5 6 | 3 2 1

4<=1? 1 nehmen .... 4<=3, 3 nehmen, 4<=6, 4 nehmen ... 6<=6, 6 nehmen. Es entfällt die Sonderbehandlung, weil die benachbarten größten Elemente durch den Vergleich zur Grenze werden. Dadurch reduziert sich die Schleife auf eine fixe Anzahl Vergleiche, ohne irgendein Bounds-Checking o.ä. .

1
EasternPremise 
Fragesteller
 01.06.2023, 15:26
@KarlRanseierIII

ahhh, jetzt habe ich es verstanden, das rückwerts speichern machen wir also nur , damit diese methode funktioniert ohne extra kopieren der werte, vielen dank du hast mir sehr geholfen

0