En classe, nous faisons des algorithmes de tri et, bien que je les comprenne bien lorsque j'en parle et que j'écris du pseudocode, j'ai des problèmes pour écrire du code réel pour eux.
Voici ma tentative en 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)
Maintenant, cela (pour autant que je sache) trie correctement, mais une fois terminé, il se boucle indéfiniment.
Comment ce code peut-il être corrigé pour que la fonction se termine correctement et trie correctement une liste de toute taille (raisonnable)?
PS Je sais que je ne devrais pas vraiment avoir d'impressions dans une fonction et que je devrais avoir un retour, mais je ne l'ai juste pas encore fait car mon code ne fonctionne pas encore vraiment.
python
algorithm
sorting
bubble-sort
Josh Hunt
la source
la source
Réponses:
Pour expliquer pourquoi votre script ne fonctionne pas pour le moment, je renommerai la variable
unsorted
ensorted
.Au début, votre liste n'est pas encore triée. Bien sûr, nous nous sommes mis
sorted
àFalse
.Dès que nous démarrons la
while
boucle, nous supposons que la liste est déjà triée. L'idée est la suivante: dès que l'on trouve deux éléments qui ne sont pas dans le bon ordre, on sesorted
remetFalse
.sorted
ne resteraTrue
que s'il n'y avait pas d'éléments dans le mauvais ordre .Il existe également de petits problèmes mineurs qui aideraient le code à être plus efficace ou plus lisible.
Dans la
for
boucle, vous utilisez la variableelement
. Techniquement, ceelement
n'est pas un élément; c'est un nombre représentant un index de liste. De plus, c'est assez long. Dans ces cas, utilisez simplement un nom de variable temporaire, commei
pour "index".La
range
commande peut également prendre un seul argument (nomméstop
). Dans ce cas, vous obtenez une liste de tous les entiers de 0 à cet argument.Le Guide de style Python recommande que les variables soient nommées en minuscules avec des traits de soulignement. C'est un petit pinaillage pour un petit script comme celui-ci; il s'agit davantage de vous habituer à ce à quoi ressemble le plus souvent le code Python.
Pour permuter les valeurs de deux variables, écrivez-les sous forme d'affectation de tuple. Le côté droit est évalué comme un tuple (disons,
(badList[i+1], badList[i])
est(3, 5)
) puis est assigné aux deux variables du côté gauche ((badList[i], badList[i+1])
).Mettez tout cela ensemble, et vous obtenez ceci:
(Au fait, j'ai également supprimé votre déclaration imprimée.)
la source
while
boucle, le plus gros élément "bouillonne" jusqu'à la fin de la liste. Ainsi, après une itération, le dernier élément est définitivement à la bonne place (et ne sera pas déplacé par itérations successives). En soustrayant 1 de la longueur, vous optimisez l'algorithme en ne triant que la sous-liste qui n'est pas encore triée (leslength-n
éléments les plus en avant de la liste). J'ai choisi de sauter cette optimisation, car il s'agit plus d'une optimisation qu'une partie vitale de l'algorithme.Put it all together, and you get this:
... eh bien, vous avez manqué celui-ci:The range command can also take just one argument (named stop).
Le but du tri à bulles est de déplacer les objets les plus lourds en bas à chaque tour, tout en déplaçant les objets les plus légers vers le haut. Dans la boucle interne, où vous comparez les éléments, vous n'avez pas à parcourir toute la liste à chaque tour . Le plus lourd est déjà placé en dernier. La variable permutée est une vérification supplémentaire afin que nous puissions marquer que la liste est maintenant triée et éviter de continuer avec des calculs inutiles.
Votre version 1, corrigée:
la source
C'est ce qui se passe lorsque vous utilisez un nom de variable de signification négative, vous devez inverser leurs valeurs. Ce qui suit serait plus facile à comprendre:
En revanche, la logique de l'algorithme est un peu décalée. Vous devez vérifier si deux éléments ont été échangés pendant la boucle for. Voici comment je l'écrirais:
la source
Votre utilisation de la variable Unsorted est incorrecte; vous voulez avoir une variable qui vous indique si vous avez permuté deux éléments; si vous avez fait cela, vous pouvez quitter votre boucle, sinon vous devez recommencer. Pour corriger ce que vous avez ici, mettez simplement le "unsorted = false" dans le corps de votre cas if; supprimez votre autre cas; et mettez "unsorted = true avant votre
for
boucle.la source
la source
#Une fonction très simple, peut être optimisée (évidemment) en diminuant l'espace problème du 2ème tableau. Mais même complexité O (n ^ 2).
la source
arr[a], arr[b] = arr[b], arr[a]
Vous avez quelques erreurs là-dedans. Le premier est de longueur, et le second est dans votre utilisation de non trié (comme indiqué par McWafflestix). Vous voudrez probablement aussi renvoyer la liste si vous allez l'imprimer:
eta: Vous avez raison, ce qui précède est un buggy comme l'enfer. Mon mal de ne pas avoir testé d'autres exemples.
la source
Je suis un nouveau débutant, j'ai commencé à lire sur Python hier. Inspiré par votre exemple, j'ai créé quelque chose peut-être plus dans le style des 80 cravates, mais néanmoins cela fonctionne un peu
la source
Le problème avec l'algorithme d'origine est que si vous aviez un nombre inférieur plus loin dans la liste, il ne l'amènerait pas à la bonne position triée. Le programme doit revenir au début à chaque fois pour s'assurer que les nombres sont triés tout au long.
J'ai simplifié le code et cela fonctionnera désormais pour n'importe quelle liste de nombres quelle que soit la liste et même s'il y a des nombres qui se répètent. Voici le code
la source
la source
alist = [54,26,93,17,77,31,44,55,20, -23, -34,16,11,11,11]
imprimer bubbleSort (alist)
la source
la source
Un exemple plus simple:
Cela prend simplement les éléments de 0 à a (en gros, tous les éléments non triés de ce tour) et le compare à son élément adjacent, et effectue un échange s'il est supérieur à son élément adjacent. À la fin du tour, le dernier élément est trié et le processus s'exécute à nouveau sans lui, jusqu'à ce que tous les éléments aient été triés.
Il n'est pas nécessaire de définir une condition, qu'elle
sort
soit vraie ou non.Notez que cet algorithme prend en considération la position des nombres uniquement lors de l'échange, donc les nombres répétés ne l'affecteront pas.
PS. Je sais que cela fait très longtemps que cette question a été publiée, mais je voulais juste partager cette idée.
la source
la source
la source
la source
la source
J'envisage d'ajouter ma solution car chaque solution ici est d'avoir
alors est devrait être
Alors, voici ma solution:
la source
Si quelqu'un est intéressé par une implémentation plus courte utilisant une compréhension de liste:
la source
Voici une variante différente du tri à bulles sans
for
boucle. Fondamentalement, vous considérez lelastIndex
dearray
et lentementdecrementing
jusqu'à ce qu'il soit le premier index du tableau.Le
algorithm
continuera à se déplacer dans le tableau comme ceci jusqu'à ce qu'une passe entière soit effectuée sans qu'aucune neswaps
se produise.La bulle est en quelque sorte en
Quadratic Time: O(n²)
matière de performances.la source
Les réponses fournies par the-fury et Martin Cote ont résolu le problème de la boucle infinie, mais mon code ne fonctionnait toujours pas correctement (pour une liste plus grande, il ne trierait pas correctement.). J'ai fini par abandonner la
unsorted
variable et j'ai utilisé un compteur à la place.Si quelqu'un pouvait fournir des conseils sur la façon d'améliorer mon code dans les commentaires, ce serait très apprécié.
la source
Essaye ça
la source
idk si cela peut vous aider après 9 ans ... c'est un simple programme de tri à bulles
la source
la source
la source
la source
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
la source