quicksort knapp daneben?
ich hab dieses quicksort programmiert:
def quicksort2(a): # hoare
if len(a) < 2:
return a
r1, r2 = 0, len(a)-1
pivot = a[random.randint(0,r2)]
while r1 < r2:
while a[r1] < pivot and r1 < r2:
r1 += 1
while a[r2] > pivot and r1 < r2:
r2 -= 1
a[r1], a[r2] = a[r2], a[r1]
r1,r2 = r1+1,r2-1
return quicksort2(a[:r1]) + quicksort2(a[r1:])
und das Ergebnis ist fast richtig, lediglich werden manchmal Zahlen im Ergebnis vertauscht. Ich hab schon mehrere gefragt, was das Problem ist, aber nicht mal ein Informatiklehrer konnte mir helfen. Auch chatgpt hat nur Schmutz geliefert, und deswegen frag ich hier. Und falls ihr denkt, ihr habt es, probiert es erst aus, weil das jeder bisher meinte.
Danke im vorraus.
1 Antwort
Beispiel:
Das Array a=[4,3,2,1]
Wir wählen das Pivot 1.
Dann kommt bei der ersten Iteration r1=0 und r2=3 raus.
Somit hast du nach Vertauschung:
[1,3,2,4]
Wegen r1,r2 = r1+1,r2-1
Ist r1 dann 1 und r2 ist 2
Am Ende der Schleife kommt dann r1=1 und r2=1 raus (da die Aufteilung passt)
Jedoch wird nun wieder r1,r2 = r1+1,r2-1
Weswegen r1 nun gleich 2 ist.
Somit wird a in die beiden Arrays [1,3] und [2,4] aufgeteilt, was aber nicht sein darf, da es so of gesplittet werden soll, sodass jedes Element aus dem linken Array kleiner sein muss, als alle Elemente aus dem rechten. Der Fehler ist hier, dass r1 um 1 zu hoch ist, du musst also korrigieren, dass dies nicht mehr passiert.
Versuch erst Mal selbst den Fehler zu finden, bevor du weiter liest.
================
Der Fehler ist, dass die Zeile
r1,r2 = r1+1,r2-1
Fehl am Platz ist. Du musst die entfernen, dann funktioniert der Algorithmus auch.
Hm, ich würde dir raten, dass du bei jedem Rekursionsschritt ausgibst, wie die derzeitige Liste aussieht, was das Pivot ist, wie die Liste unsortiert wurdet und was ri ist.
Dann sollte es vielleicht etwas leichter sein, den Fehler zu erkennen.
das hatte ich schon ausprobiert, aber kam nicht darauf. die endgültige lösung war es scheinbar, nach dem vertauschen, nur r1 zu erweitern, um loops zu entkommen, aber nicht r2 zu ändern. bin nur durch zufall drauf gekommen, aber kanns mir auch nicht ganz erklären, wieso das einen so großen unterschied macht. evtl verhindert das, dass der pivot in die rechte liste kommt(?)
dann hängt es aber manchmal komplett, ich glaube weil es entweder 2 zahlen immer und immer wieder tauscht, oder weil die liste nicht klein genug wird zum rekursionsausgang