Im Unterricht machen wir Sortieralgorithmen und obwohl ich sie gut verstehe, wenn ich über sie spreche und Pseudocode schreibe, habe ich Probleme, tatsächlichen Code für sie zu schreiben.
Dies ist mein Versuch in Python:
mylist = [12, 5, 13, 8, 9, 65]
def bubble(badList):
length = len(badList) - 1
unsorted = True
while unsorted:
for element in range(0,length):
unsorted = False
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
print badList
else:
unsorted = True
print bubble(mylist)
Nun, dies wird (soweit ich das beurteilen kann) richtig sortiert, aber sobald es fertig ist, wird es nur auf unbestimmte Zeit wiederholt.
Wie kann dieser Code behoben werden, damit die Funktion ordnungsgemäß beendet und eine Liste mit einer beliebigen (angemessenen) Größe sortiert wird?
PS Ich weiß, ich sollte eigentlich keine Ausdrucke in einer Funktion haben und ich sollte eine Rückgabe haben, aber ich habe das nur noch nicht getan, da mein Code noch nicht wirklich funktioniert.
python
algorithm
sorting
bubble-sort
Josh Hunt
quelle
quelle
Antworten:
Um zu erklären, warum Ihr Skript gerade nicht funktioniert, benenne ich die Variable
unsorted
in umsorted
.Ihre Liste ist zunächst noch nicht sortiert. Natürlich machen wir uns
sorted
daranFalse
.Sobald wir die
while
Schleife starten , gehen wir davon aus, dass die Liste bereits sortiert ist. Die Idee ist folgende: Sobald wir zwei Elemente finden, die nicht in der richtigen Reihenfolge sind, kehren wirsorted
zurückFalse
.sorted
wirdTrue
nur bleiben , wenn es keine Elemente in der falschen Reihenfolge gab .Es gibt auch kleinere kleine Probleme, die dazu beitragen würden, dass der Code effizienter oder lesbarer wird.
In der
for
Schleife verwenden Sie die Variableelement
. Technischelement
ist kein Element; Es ist eine Zahl, die einen Listenindex darstellt. Außerdem ist es ziemlich lang. Verwenden Sie in diesen Fällen einfach einen temporären Variablennamen, z. B.i
für "Index".Der
range
Befehl kann auch nur ein Argument (benanntstop
) annehmen . In diesem Fall erhalten Sie eine Liste aller Ganzzahlen von 0 bis zu diesem Argument.Der Python Style Guide empfiehlt, Variablen in Kleinbuchstaben mit Unterstrichen zu benennen. Dies ist ein sehr kleiner Trottel für ein kleines Skript wie dieses; Es ist mehr, um Sie an den Python-Code zu gewöhnen, der am häufigsten ähnelt.
Um die Werte zweier Variablen auszutauschen, schreiben Sie sie als Tupelzuweisung. Die rechte Seite wird als Tupel ausgewertet (z. B.
(badList[i+1], badList[i])
ist(3, 5)
) und dann den beiden Variablen auf der linken Seite zugewiesen ((badList[i], badList[i+1])
).Füge alles zusammen und du bekommst folgendes:
(Ich habe übrigens auch Ihre Druckerklärung entfernt.)
quelle
while
Schleife "sprudelt" das größte Element bis zum Ende der Liste. Daher befindet sich das letzte Element nach einer Iteration definitiv an der richtigen Stelle (und wird durch aufeinanderfolgende Iterationen nicht verschoben). Durch Subtrahieren von 1 von der Länge optimieren Sie den Algorithmus, indem Sie nur die noch nicht sortierte Unterliste sortieren (dielength-n
vordersten Elemente der Liste). Ich habe mich entschieden, diese Optimierung zu überspringen, da sie eher eine Optimierung als ein wesentlicher Bestandteil des Algorithmus ist.Put it all together, and you get this:
... nun, du hast diesen verpasst:The range command can also take just one argument (named stop).
Das Ziel der Blasensortierung ist es, die schwereren Gegenstände in jeder Runde unten zu bewegen , während die leichteren Gegenstände nach oben bewegt werden. In der inneren Schleife, in der Sie die Elemente vergleichen, müssen Sie nicht in jeder Runde die gesamte Liste durchlaufen . Der schwerste ist bereits zuletzt platziert. Die ausgetauschte Variable ist eine zusätzliche Prüfung, damit wir markieren können, dass die Liste jetzt sortiert ist, und vermeiden, mit unnötigen Berechnungen fortzufahren.
Ihre Version 1, korrigiert:
quelle
Dies passiert, wenn Sie einen Variablennamen mit negativer Bedeutung verwenden und dessen Werte invertieren müssen. Folgendes wäre leichter zu verstehen:
Andererseits ist die Logik des Algorithmus etwas abweichend. Sie müssen überprüfen, ob zwei Elemente während der for-Schleife ausgetauscht wurden. So würde ich es schreiben:
quelle
Ihre Verwendung der unsortierten Variablen ist falsch. Sie möchten eine Variable haben, die Ihnen sagt, ob Sie zwei Elemente ausgetauscht haben. Wenn Sie dies getan haben, können Sie Ihre Schleife verlassen, andernfalls müssen Sie die Schleife erneut durchführen. Um zu korrigieren, was Sie hier haben, fügen Sie einfach "unsortiert = falsch" in den Text Ihres if-Falls ein. Entfernen Sie Ihren anderen Fall. und setzen Sie "unsorted = true" vor Ihre
for
Schleife.quelle
quelle
# Eine sehr einfache Funktion, die (offensichtlich) optimiert werden kann, indem der Problembereich des 2. Arrays verringert wird. Aber gleiche O (n ^ 2) -Komplexität.
quelle
arr[a], arr[b] = arr[b], arr[a]
Sie haben ein paar Fehler drin. Die erste ist lang und die zweite wird von unsortiert verwendet (wie von McWafflestix angegeben). Sie möchten die Liste wahrscheinlich auch zurückgeben, wenn Sie sie drucken möchten:
eta: Du hast recht, das obige ist verdammt fehlerhaft. Mein schlechtes, weil ich nicht durch einige weitere Beispiele getestet habe.
quelle
Ich bin ein frischer Anfänger und habe gestern angefangen, über Python zu lesen. Inspiriert von Ihrem Beispiel habe ich etwas geschaffen, das vielleicht mehr im 80er-Jahre-Stil ist, aber trotzdem funktioniert es irgendwie
quelle
Das Problem mit dem ursprünglichen Algorithmus ist, dass wenn Sie eine niedrigere Zahl weiter in der Liste hätten, diese nicht an die richtige sortierte Position gebracht würde. Das Programm muss jedes Mal den Anfang zurückgehen, um sicherzustellen, dass die Zahlen vollständig sortiert sind.
Ich habe den Code vereinfacht und er funktioniert jetzt für jede Liste von Zahlen, unabhängig von der Liste und selbst wenn sich Zahlen wiederholen. Hier ist der Code
quelle
quelle
alist = [54,26,93,17,77,31,44,55,20, -23, -34,16,11,11,11]
print bubleSort (alist)
quelle
quelle
Ein einfacheres Beispiel:
Dies nimmt einfach die Elemente von 0 nach a (im Grunde alle unsortierten Elemente in dieser Runde) und vergleicht sie mit dem benachbarten Element und führt einen Swap durch, wenn sie größer als das benachbarte Element sind. Am Ende der Runde wird das letzte Element sortiert und der Prozess wird erneut ohne dieses Element ausgeführt, bis alle Elemente sortiert wurden.
Es besteht keine Notwendigkeit für eine Bedingung, ob sie
sort
wahr ist oder nicht.Beachten Sie, dass dieser Algorithmus die Position der Zahlen nur beim Tauschen berücksichtigt, sodass wiederholte Zahlen keine Auswirkungen darauf haben.
PS. Ich weiß, dass es sehr lange her ist, dass diese Frage gestellt wurde, aber ich wollte diese Idee nur teilen.
quelle
quelle
quelle
quelle
quelle
Ich denke darüber nach, meine Lösung hinzuzufügen, weil es hier jemals eine Lösung gibt
dann sollte es sein
Also, hier ist meine Lösung:
quelle
Wenn jemand an einer kürzeren Implementierung mit Listenverständnis interessiert ist:
quelle
Hier ist eine andere Variante der Blasensortierung ohne
for
Schleife. Grundsätzlich betrachten Sie daslastIndex
vonarray
und langsamdecrementing
bis zum ersten Index des Arrays.Der
algorithm
wird sich so weiter durch das Array bewegen, bis ein vollständiger Durchlauf ohneswaps
Auftreten erfolgt ist.Die Blase ist im Grunde genommen eine Art
Quadratic Time: O(n²)
Leistung.quelle
Die Antworten von the-fury und Martin Cote haben das Problem der Endlosschleife behoben, aber mein Code würde immer noch nicht richtig funktionieren (für eine größere Liste würde er nicht richtig sortieren.). Am Ende habe ich die
unsorted
Variable verworfen und stattdessen einen Zähler verwendet.Wenn jemand in den Kommentaren Hinweise geben könnte, wie ich meinen Code verbessern kann, wäre ich sehr dankbar.
quelle
Versuche dies
quelle
idk, wenn dir das nach 9 Jahren helfen könnte ... es ist ein einfaches Programm zum Sortieren von Blasen
quelle
quelle
quelle
quelle
def bubbleSort(a): def swap(x, y): temp = a[x] a[x] = a[y] a[y] = temp #outer loop for j in range(len(a)): #slicing to the center, inner loop, python style for i in range(j, len(a) - j):
#find the min index and swap if a[i] < a[j]: swap(j, i) #find the max index and swap if a[i] > a[len(a) - j - 1]: swap(len(a) - j - 1, i) return a
quelle