Пузырь Python не сортирует весь список [дубликат]

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

if(a==b) {
    ;
}
127
задан Bill the Lizard 15 September 2012 в 03:34
поделиться

19 ответов

Чтобы объяснить, почему ваш скрипт не работает прямо сейчас, я переименую переменную 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 для «index».
    for i in range(0, length):
    
  • Команда range также может принимать только один аргумент (с именем stop). В этом случае вы получите список всех целых чисел от 0 до этого аргумента.
    for i in range(length):
    
  • Руководство по стилю Python Style рекомендует, чтобы переменные назывались в нижнем регистре с символами подчеркивания. Это очень незначительная нить для маленького скрипта, подобного этому; это больше, чтобы вы привыкли к тому, что код 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

(Я также удалил ваш оператор печати.)

120
ответ дан Wesley 20 August 2018 в 13:18
поделиться
  • 1
    Как раз на этом последнем бит кода, пузырь ничего не возвращает, поэтому конечный результат заключается в том, что печатается «Нет». Вероятно, вы хотите либо вернуть список, либо сделать пузырь (my_list), а затем распечатать my_list. – Tung Nguyen 11 June 2009 в 08:50
  • 2
    +1 хорошо структурированный, четкий совет. Приятно видеть, что вы читаете читателя через то, что вы сделали, и почему, а не просто быстро напишите. – Tom Leys 11 June 2009 в 10:12
  • 3
    Я программист на C #, так что это может быть только потому, что я не получаю Python, но вам не нужно что-то в цикле while, чтобы вычесть 1 из длины, чтобы получить обычный алгоритм сортировки пузырьков? – Martin Brown 11 June 2009 в 10:43
  • 4
    Это наивная (но не некорректная) реализация Bubble Sort. После каждой итерации цикла while наибольший элемент «пузырится вверх», до конца списка. Таким образом, после одной итерации последний элемент определенно находится в нужном месте (и не будет перемещаться последовательными итерациями). Вычитая 1 из длины, вы оптимизируете алгоритм, только сортируя подсписку, который еще не отсортирован (передние элементы length-n в списке). Я решил пропустить эту оптимизацию, так как это скорее оптимизация, чем жизненно важная часть алгоритма. – Wesley 11 June 2009 в 11:14
  • 5
    Put it all together, and you get this: ... ну, вы пропустили это: The range command can also take just one argument (named stop). – Peter Perháč 11 June 2009 в 12:34
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 )
0
ответ дан aldo núñez 20 August 2018 в 13:18
поделиться
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
ответ дан AstroCB 20 August 2018 в 13:18
поделиться

Неправильное использование переменной Unsorted; вы хотите иметь переменную, которая сообщает вам, если вы заменили два элемента; если вы это сделали, вы можете выйти из цикла, иначе вам нужно снова зациклиться. Чтобы исправить то, что у вас здесь, просто поместите «unsorted = false» в тело вашего случая if; удалите свой другой случай; и поставьте «unsorted = true» перед вашим циклом for.

8
ответ дан BCS 20 August 2018 в 13:18
поделиться
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
ответ дан Bryan 20 August 2018 в 13:18
поделиться
  • 1
    Пожалуйста, не просто отправляйте код, объясняются хорошие ответы – Sterling Archer 6 April 2018 в 00:33
  • 2
    Хотя этот код может ответить на вопрос, предоставляя дополнительный контекст относительно , как и / или , почему он решает проблему, улучшит долгосрочную ценность ответа. – Alexander 6 April 2018 в 03:07

Я свежий новичок, начал читать о 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)
2
ответ дан Igor 20 August 2018 в 13:18
поделиться

Ответы, предоставленные the-fury и Martin Cote, фиксировали проблему бесконечного цикла, но мой код все равно не работал бы корректно (для большего списка он не будет правильно сортироваться.). Я закончил тем, что перебрал переменную 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)

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

0
ответ дан Josh Hunt 20 August 2018 в 13:18
поделиться
  • 1
    Вы можете ускорить сортировку пузырьков, пропуская часть вашего списка, которую вы знаете, уже отсортированы (из-за предыдущих итераций). См. ru.wikipedia.org/wiki/Bubble_sort#Alternative_implementations – Blorgbeard 22 May 2009 в 00:38
  • 2
    снова все, что вам действительно нужно сделать, это использовать логическое значение (называть его нетронутым). объявите его вне вашей петли; цикл до нетронутого = true. внутри цикла while, нетронутым, чтобы быть истинным; в теле вашего if, установленного нетронутым, чтобы быть ложным. Делая это, вы можете остановить другой случай. таким образом, если вы когда-либо переключаете два элемента, ваш цикл будет продолжен; если вы этого не сделаете, цикл не будет. – Paul Sonier 22 May 2009 в 00:38

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

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
9
ответ дан Martin Cote 20 August 2018 в 13:18
поделиться
  • 1
    +1 Набрал что-то с тем же эффектом. – Stephan202 21 May 2009 в 22:55
  • 2
    Слишком плохо, что нет «НЕПРАВИЛЬНОГО». Я могу ответить за этот ответ. Я думаю, что этот вопрос и ответы - и особенно голосование - должны появиться в следующий раз, когда Джоэл Спольский расскажет о том, насколько хорошо он настроил социальные взаимодействия на stackoverflow. – Daniel Martin 23 May 2009 в 02:55
  • 3
    Вы, ребята, правы, я преждевременно ответил на это. Извини за это. – Martin Cote 24 May 2009 в 03:38
  • 4
    @ Мартин - и я должен указать, что я больше удивлен или шокирован голосованием, чем ответом. Система репутации побуждает вас сразу же получить этот первый ответ. Сломанная часть - это то, как отклонен неправильный ответ. – Daniel Martin 24 May 2009 в 16:52
  • 5
    Я подозреваю, что большинство людей голосует, не понимая вопроса в первую очередь (точно так же, как я ответил на вопрос). OTOH, человек, который задает вопрос, имеет привилегию выбора «правильного» ответа впоследствии. – Martin Cote 24 May 2009 в 17:23
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 20 August 2018 в 13:18
поделиться
  • 1
    Я действительно верю, что вопрос был более похожим на «Как можно зафиксировать этот код», а не «что такое ваш пузырь»? – Josh Hunt 22 May 2009 в 00:18
  • 2
    вы абсолютно правы, но делать это правильно, более важно – mtasic85 22 May 2009 в 00:28
  • 3
    Правда, возможно, mtasic ... но все, что помечено как домашнее задание, наиболее наглядно подстраивается, а не переписывается (особенно, когда оно помечено домашним заданием OP). – Jarret Hardie 22 May 2009 в 01:24
  • 4
    Это идеальная переиздание учебника C-пузыря, который большинство людей изучает. Я написал то же самое. – Lakshman Prasad 18 June 2009 в 12:46
  • 5
    добавление хорошей информации полезно на мой взгляд. так что хороший ответ. Предположим, вы можете использовать флаг, чтобы разорвать его как можно раньше. – Grijesh Chauhan 28 September 2013 в 19:43

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

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
11
ответ дан Nick Dandoulakis 20 August 2018 в 13:18
поделиться

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

-3
ответ дан Nik Radaev 20 August 2018 в 13:18
поделиться
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
ответ дан Paul Roub 20 August 2018 в 13:18
поделиться
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 20 August 2018 в 13:18
поделиться
  • 1
    Пожалуйста, откорректируйте образец кода правильно: это, конечно, особенно важно в Python. Вы также можете объяснить, почему ваше решение стоит рассмотреть, учитывая, что есть также ответ с 100 голосами – kdopen 17 February 2015 в 00:22

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

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

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
ответ дан sashkello 20 August 2018 в 13:18
поделиться

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

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: Вы правы, это неправильно, черт возьми. Мой плохой для не тестирования через несколько примеров.

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 20 August 2018 в 13:18
поделиться
  • 1
    Не должно быть "unsorted = False" быть вне цикла for? – Svante 22 May 2009 в 00:54
  • 2
    У него было еще несколько проблем, чем это;) – Trevor Oke 22 May 2009 в 01:05

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

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 истинным или нет.

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

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

2
ответ дан txsaw1 20 August 2018 в 13:18
поделиться

# Очень простая функция, может быть оптимизирована (очевидно) путем уменьшения проблемного пространства 2-го массива. Но такая же сложность 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 20 August 2018 в 13:18
поделиться
  • 1
    Это немного меньше связано с тем, как вы можете менять значения в Python: arr[a], arr[b] = arr[b], arr[a] – Makoto 15 April 2013 в 00:07
  • 2
    @Makoto хорошая точка, исправлена. – Waqas 15 April 2013 в 17:51
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 20 August 2018 в 13:18
поделиться
  • 1
    Пузырь большего размера до конца. И декремент счетчика конца, "n" так что вам не придется сравнивать его снова. Продолжайте цикл while, пока есть обмены. Худший случай: O (N ^ 2) Лучший случай: O (N) – Zile Rehman 5 July 2014 в 07:44
0
ответ дан vivek shinde 31 October 2018 в 10:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: