web-dev-qa-db-fra.com

Bubble Sort devoirs

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.

128
Josh Hunt

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 Trueseulement 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.)

123
Wesley

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
11
Nick Dandoulakis

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
9
Martin Cote

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.

8
Paul Sonier
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
5
mtasic85

#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 
3
Waqas

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.

2
txsaw1
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
2
Zile Rehman

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)
2
Igor

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)
2
weinberg
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
2
pinkopink
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) 

2
pythonnewbie

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
2
Trevor Oke
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
1
Rocky
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 )
1
aldo núñez
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]))
1
Luke Willey
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
0
Amandeep Singh
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 
0
user11689497

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)
0
vivek shinde

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]
0
carl

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é.

0
Josh Hunt

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]
0
Artiom Kozyrev