Вопрос

В классе мы занимаемся алгоритмами сортировки, и хотя я прекрасно их понимаю, когда говорю о них и пишу псевдокод, у меня возникают проблемы с написанием для них реального кода.

Это моя попытка на 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)

Итак, это (насколько я могу судить) сортируется правильно, но как только оно заканчивается, оно просто зацикливается на неопределенный срок.

Как можно исправить этот код, чтобы функция завершалась правильно и корректно сортировала список любого (разумного) размера?

P.S.Я знаю, что на самом деле у меня не должно быть отпечатков в функции, и у меня должен быть возврат, но я просто еще этого не сделал, поскольку мой код еще не работает.

Это было полезно?

Решение

Чтобы объяснить, почему ваш скрипт сейчас не работает, я переименую переменную unsorted к sorted.

Во-первых, ваш список еще не отсортирован.Конечно, мы поставили sorted к False.

Как только мы начнем while цикла, мы предполагаем, что список уже отсортирован.Идея такова:как только мы находим два элемента, которые расположены не в правильном порядке, мы устанавливаем sorted вернуться к False. sorted останется True только если не было элементов в неправильном порядке.

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.

Есть также небольшие проблемы, которые помогут сделать код более эффективным и читабельным.

  • в for цикл, вы используете переменную element.Технически, element не является элементом;это число, представляющее индекс списка.Кроме того, это довольно долго.В таких случаях просто используйте имя временной переменной, например i для «индекса».

    for i in range(0, length):
    
  • А range команда также может принимать только один аргумент (с именем stop).В этом случае вы получите список всех целых чисел от 0 до этого аргумента.

    for i in range(length):
    
  • А Руководство по стилю Python рекомендует называть переменные строчными буквами с подчеркиванием.Это очень незначительная придирка для такого небольшого сценария;это скорее для того, чтобы вы привыкли к тому, что чаще всего напоминает код Python.

    def bubble(bad_list):
    
  • Чтобы поменять местами значения двух переменных, запишите их как назначение кортежа.Правая часть оценивается как кортеж (скажем, (badList[i+1], badList[i]) является (3, 5)), а затем присваивается двум переменным в левой части ((badList[i], badList[i+1])).

    bad_list[i], bad_list[i+1] = bad_list[i+1], bad_list[i]
    

Сложите все это вместе, и вы получите следующее:

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

(Кстати, я удалил и ваше заявление о печати.)

Другие советы

Цель пузырьковой сортировки — переместить тяжелее предметы внизу в каждом раунде, перемещая более легкий предметы вверх.Во внутреннем цикле, где вы сравниваете элементы, вам не нужно перебирать весь список на каждом ходусамый тяжелый уже стоит последним.А поменяли местами переменная — это дополнительная проверка, позволяющая отметить, что список теперь отсортирован, и избежать продолжения ненужных вычислений.

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

Ваша версия 1, исправленная:

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

Вот что происходит, когда вы используете имена переменных отрицательного значения, вам нужно инвертировать их значения.Было бы легче понять следующее:

sorted = False
while not sorted:
    ...

С другой стороны, логика алгоритма немного нарушена.Вам нужно проверить, поменялись ли местами два элемента во время цикла for.Вот как бы я это написал:

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

Вы используете переменную Unsorted неправильно;вы хотите иметь переменную, которая сообщит вам, поменяли ли вы местами два элемента;если вы это сделали, вы можете выйти из цикла, в противном случае вам придется повторить цикл снова.Чтобы исправить то, что у вас есть, просто поместите «unsorted = false» в тело вашего случая if;удалите еще случай;и поставьте «unsorted = true» перед вашим 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

#Очень простая функция, которую можно оптимизировать (очевидно), уменьшив проблемное пространство второго массива.Но та же сложность 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 

У вас там пара ошибок.Первый - это длина, а второй - использование вами несортированного (как утверждает Макваффлестикс).Вероятно, вы также захотите вернуть список, если собираетесь его распечатать:

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)

эта:Вы правы, вышеописанное чертовски глючное.Я виноват, что не проверил еще несколько примеров.

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

Я новичок, вчера начал читать о Python.Вдохновившись вашим примером, я создал что-то, может, больше в стиле 80-х, но тем не менее это вроде как работает.

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)

Проблема исходного алгоритма заключается в том, что если бы дальше в списке было меньшее число, оно не привело бы его в правильную отсортированную позицию.Программе необходимо каждый раз возвращаться к началу, чтобы гарантировать, что числа отсортированы до конца.

Я упростил код и теперь он будет работать для любого списка чисел независимо от списка и даже если есть повторяющиеся числа.Вот код

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(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
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

список = [54,26,93,17,77,31,44,55,20,-23,-34,16,11,11,11]

распечатать пузырьковую сортировку (список)

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

Более простой пример:

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

Это просто берет элементы от 0 до a (по сути, все неотсортированные элементы в этом раунде) и сравнивает их с соседним элементом и делает замену, если он больше, чем соседний элемент.В конце раунда сортируется последний элемент, и процесс повторяется без него, пока все элементы не будут отсортированы.

Нет необходимости в условии, sort правда это или нет.

Обратите внимание, что этот алгоритм учитывает положение чисел только при перестановке, поэтому повторяющиеся числа не повлияют на него.

ПС.Я знаю, что прошло очень много времени с тех пор, как этот вопрос был опубликован, но я просто хотел поделиться этой идеей.

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 __name__ == '__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]))

Ответы, предоставленные the-fury и Мартином Коутом, устранили проблему бесконечного цикла, но мой код по-прежнему работал неправильно (для большего списка он не будет правильно сортироваться).В итоге я отказался от unsorted переменную и вместо нее использовал счетчик.

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 __name__ == '__main__':
    mylist = [90, 10, 2, 76, 17, 66, 57, 23, 57, 99]
    print bubble(mylist)

Если бы кто-нибудь мог дать какие-либо указания о том, как улучшить мой код в комментариях, я был бы очень признателен.

Попробуй это

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)

Я хотел бы поделиться своим решением:

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_

Тестовый пример:

a = [8,1,2,4,1,3,5,1,5,6,1,8]
bubble_sort(a)

Результат:

[1, 1, 1, 1, 2, 3, 4, 5, 5, 6, 8, 8]

Не знаю, поможет ли это вам через 9 лет...это простая программа пузырьковой сортировки

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top