En classe, nous utilisons des algorithmes de tri et, bien que je les comprenne très bien lorsque je parle d’eux et que j’écris un pseudocode, j’ai du mal à écrire le 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, ceci (pour autant que je sache) trie correctement, mais une fois terminé, il tourne en 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)?
P.S. 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 pas encore fait car mon code ne fonctionne pas encore vraiment.
Pour expliquer pourquoi votre script ne fonctionne pas actuellement, je vais renommer la variable unsorted
en sorted
.
Au début, votre liste n'est pas encore triée. Bien sûr, nous avons défini sorted
sur False
.
Dès que nous commençons la boucle while
, nous supposons que la liste est déjà triée. L'idée est la suivante: dès que nous trouvons deux éléments qui ne sont pas dans le bon ordre, nous redéfinissons sorted
sur False
. sorted
restera True
seulement s'il n'y avait aucun élément dans le mauvais ordre.
sorted = False # We haven't started sorting yet
while not sorted:
sorted = True # Assume the list is now sorted
for element in range(0, length):
if badList[element] > badList[element + 1]:
sorted = False # We found two elements in the wrong order
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
# We went through the whole list. At this point, if there were no elements
# in the wrong order, sorted is still True. Otherwise, it's false, and the
# while loop executes again.
Il existe également des problèmes mineurs qui pourraient aider le code à être plus efficace ou plus lisible.
Dans la boucle for
, vous utilisez la variable element
. Techniquement, element
n'est pas un élément; c'est un nombre représentant un index de liste. En outre, c'est assez long. Dans ces cas, utilisez simplement un nom de variable temporaire, tel que i
pour "index".
for i in range(0, length):
La commande range
peut également ne prendre qu'un seul argument (nommé stop
). Dans ce cas, vous obtenez une liste de tous les entiers de 0 à cet argument.
for i in range(length):
Le Guide de style Python recommande de nommer les variables en minuscule avec des traits de soulignement. C'est un très mineur nitpick pour un petit script comme celui-ci; c'est plus pour vous habituer à ce à quoi le code Python ressemble le plus souvent.
def bubble(bad_list):
Pour échanger les valeurs de deux variables, écrivez-les en tant qu'affectation Tuple. Le côté droit est évalué en tant que tuple (par exemple, (badList[i+1], badList[i])
est (3, 5)
), puis est attribué aux deux variables du côté gauche ((badList[i], badList[i+1])
).
bad_list[i], bad_list[i+1] = bad_list[i+1], bad_list[i]
Mettez tout cela ensemble et vous obtenez ceci:
my_list = [12, 5, 13, 8, 9, 65]
def bubble(bad_list):
length = len(bad_list) - 1
sorted = False
while not sorted:
sorted = True
for i in range(length):
if bad_list[i] > bad_list[i+1]:
sorted = False
bad_list[i], bad_list[i+1] = bad_list[i+1], bad_list[i]
bubble(my_list)
print my_list
(Au fait, j'ai aussi supprimé votre relevé d'impression.)
L'objectif du tri à bulles est de déplacer les éléments plus lourds en bas de chaque tour, tout en déplaçant les éléments plus légers vers le haut. Dans la boucle intérieure, où vous comparez les éléments, vous n'avez pas à parcourir la liste entière à chaque tour . Le plus lourd est déjà placé en dernier. La variable swapped est une vérification supplémentaire permettant de marquer que la liste est maintenant triée et d'éviter de continuer des calculs inutiles.
def bubble(badList):
length = len(badList)
for i in range(0,length):
swapped = False
for element in range(0, length-i-1):
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
swapped = True
if not swapped: break
return badList
Votre version 1, corrigée:
def bubble(badList):
length = len(badList) - 1
unsorted = True
while unsorted:
unsorted = False
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
unsorted = True
#print badList
#else:
#unsorted = True
return badList
C'est ce qui se produit lorsque vous utilisez un nom de variable de sens négatif, vous devez inverser leurs valeurs. Ce qui suit serait plus facile à comprendre:
sorted = False
while not sorted:
...
D'autre part, la logique de l'algorithme est un peu décalée. Vous devez vérifier si deux éléments ont été permutés pendant la boucle for. Voici comment je l'écrirais:
def bubble(values):
length = len(values) - 1
sorted = False
while not sorted:
sorted = True
for element in range(0,length):
if values[element] > values[element + 1]:
hold = values[element + 1]
values[element + 1] = values[element]
values[element] = hold
sorted = False
return values
Votre utilisation de la variable non triée est incorrecte; vous voulez avoir une variable qui vous indique si vous avez échangé deux éléments; si vous avez fait cela, vous pouvez sortir de votre boucle, sinon, vous devez refaire une boucle. Pour réparer ce que vous avez ici, il suffit de mettre "unsorted = false" dans le corps de votre if, enlève ton autre cas; et mettez "unsorted = true" avant votre boucle for
.
def bubble_sort(l):
for passes_left in range(len(l)-1, 0, -1):
for index in range(passes_left):
if l[index] < l[index + 1]:
l[index], l[index + 1] = l[index + 1], l[index]
return l
#Une fonction très simple, peut être optimisée (évidemment) en diminuant l'espace de problème du second tableau. Mais même complexité O (n ^ 2).
def bubble(arr):
l = len(arr)
for a in range(l):
for b in range(l-1):
if (arr[a] < arr[b]):
arr[a], arr[b] = arr[b], arr[a]
return arr
Un exemple plus simple:
a = len(alist)-1
while a > 0:
for b in range(0,a):
#compare with the adjacent element
if alist[b]>=alist[b+1]:
#swap both elements
alist[b], alist[b+1] = alist[b+1], alist[b]
a-=1
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éterminer si la variable sort
est vraie ou non.
Notez que cet algorithme prend en compte la position des nombres uniquement lors de la permutation; ainsi, les nombres répétés ne l’affecteront pas.
PS. Je sais que cette question a été postée il y a très longtemps, mais je voulais juste partager cette idée.
def bubble_sort(l):
exchanged = True
iteration = 0
n = len(l)
while(exchanged):
iteration += 1
exchanged = False
# Move the largest element to the end of the list
for i in range(n-1):
if l[i] > l[i+1]:
exchanged = True
l[i], l[i+1] = l[i+1], l[i]
n -= 1 # Largest element already towards the end
print 'Iterations: %s' %(iteration)
return l
Je suis un débutant frais, j'ai commencé à lire sur Python hier . Inspiré par votre exemple, j'ai créé quelque chose de peut-être plus dans le style des 80 cravates, mais néanmoins cela fonctionne un peu
lista1 = [12, 5, 13, 8, 9, 65]
i=0
while i < len(lista1)-1:
if lista1[i] > lista1[i+1]:
x = lista1[i]
lista1[i] = lista1[i+1]
lista1[i+1] = x
i=0
continue
else:
i+=1
print(lista1)
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'aurait pas amené à la position triée correcte. Le programme doit revenir au début à chaque fois pour s'assurer que les chiffres sont bien triés.
J'ai simplifié le code et il fonctionnera désormais pour n'importe quelle liste de numéros, peu importe la liste et même s'il y a des numéros répétés. Voici le code
mylist = [9, 8, 5, 4, 12, 1, 7, 5, 2]
print mylist
def bubble(badList):
length = len(badList) - 1
element = 0
while element < length:
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
element = 0
print badList
else:
element = element + 1
print bubble(mylist)
def bubble_sort(a):
t = 0
sorted = False # sorted = False because we have not began to sort
while not sorted:
sorted = True # Assume sorted = True first, it will switch only there is any change
for key in range(1,len(a)):
if a[key-1] > a[key]:
sorted = False
t = a[key-1]; a[key-1] = a[key]; a[key] = t;
print a
def bubbleSort(alist):
if len(alist) <= 1:
return alist
for i in range(0,len(alist)):
print "i is :%d",i
for j in range(0,i):
print "j is:%d",j
print "alist[i] is :%d, alist[j] is :%d"%(alist[i],alist[j])
if alist[i] > alist[j]:
alist[i],alist[j] = alist[j],alist[i]
return alist
alist = [54,26,93,17,77,31,44,55,20, -23, -34,16,11,11,11]
print bubbleSort (alist)
Vous avez quelques erreurs là-dedans. Le premier est en longueur et le second est dans votre utilisation de non trié (comme indiqué par McWafflestix). Vous voudrez probablement aussi retourner la liste si vous voulez l’imprimer:
mylist = [12, 5, 13, 8, 9, 65]
def bubble(badList):
length = len(badList) - 2
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
unsorted = True
return badList
print bubble(mylist)
eta: Vous avez raison, ce qui précède est un vrai buggy. Mon mal pour ne pas tester à travers quelques exemples plus.
def bubble2(badList):
swapped = True
length = len(badList) - 2
while swapped:
swapped = False
for i in range(0, length):
if badList[i] > badList[i + 1]:
# swap
hold = badList[i + 1]
badList[i + 1] = badList[i]
badList[i] = hold
swapped = True
return badList
def bubble_sort(li):
l = len(li)
tmp = None
sorted_l = sorted(li)
while (li != sorted_l):
for ele in range(0,l-1):
if li[ele] > li[ele+1]:
tmp = li[ele+1]
li[ele+1] = li [ele]
li[ele] = tmp
return li
def bubbleSort ( arr ):
swapped = True
length = len ( arr )
j = 0
while swapped:
swapped = False
j += 1
for i in range ( length - j ):
if arr [ i ] > arr [ i + 1 ]:
# swap
tmp = arr [ i ]
arr [ i ] = arr [ i + 1]
arr [ i + 1 ] = tmp
swapped = True
if __== '__main__':
# test list
a = [ 67, 45, 39, -1, -5, -44 ];
print ( a )
bubbleSort ( a )
print ( a )
def bubblesort(array):
for i in range(len(array)-1):
for j in range(len(array)-1-i):
if array[j] > array[j+1]:
array[j], array[j+1] = array[j+1], array[j]
return(array)
print(bubblesort([3,1,6,2,5,4]))
def bubble_sort(l):
for i in range(len(l) -1):
for j in range(len(l)-i-1):
if l[j] > l[j+1]:
l[j],l[j+1] = l[j+1], l[j]
return l
def merge_bubble(arr):
k = len(arr)
while k>2:
for i in range(0,k-1):
for j in range(0,k-1):
if arr[j] > arr[j+1]:
arr[j],arr[j+1] = arr[j+1],arr[j]
return arr
break
else:
if arr[0] > arr[1]:
arr[0],arr[1] = arr[1],arr[0]
return arr
Essaye ça
a = int(input("Enter Limit"))
val = []
for z in range(0,a):
b = int(input("Enter Number in List"))
val.append(b)
for y in range(0,len(val)):
for x in range(0,len(val)-1):
if val[x]>val[x+1]:
t = val[x]
val[x] = val[x+1]
val[x+1] = t
print(val)
idk si cela pourrait vous aider après 9 ans ... c'est un programme de tri simple en bulle
l=[1,6,3,7,5,9,8,2,4,10]
for i in range(1,len(l)):
for j in range (i+1,len(l)):
if l[i]>l[j]:
l[i],l[j]=l[j],l[i]
Les réponses fournies par the-fury et Martin Cote ont résolu le problème de la boucle infinie, mais mon code ne fonctionnerait toujours pas correctement (pour une liste plus longue, le tri ne serait pas correct). J'ai fini par abandonner la variable unsorted
et utilisé un compteur à la place.
def bubble(badList):
length = len(badList) - 1
n = 0
while n < len(badList):
for element in range(0,length):
if badList[element] > badList[element + 1]:
hold = badList[element + 1]
badList[element + 1] = badList[element]
badList[element] = hold
n = 0
else:
n += 1
return badList
if __== '__main__':
mylist = [90, 10, 2, 76, 17, 66, 57, 23, 57, 99]
print bubble(mylist)
Si quelqu'un pouvait donner des indications sur la manière d'améliorer mon code dans les commentaires, ce serait très apprécié.
J'aimerais partager ma solution:
def bubble_sort(list_):
for i in range(len(list_)):
for j in range(i, len(list_)):
if a[i] > a[j]:
a[i], a[j] = a[j], a[i]
return list_
Exemple de test:
a = [8,1,2,4,1,3,5,1,5,6,1,8]
bubble_sort(a)
Résultat:
[1, 1, 1, 1, 2, 3, 4, 5, 5, 6, 8, 8]