stringtranslate.com

Сортировка пузырьком

Сортировка пузырьком , иногда называемая сортировкой с погружением , представляет собой простой алгоритм сортировки , который многократно проходит по входному списку элемент за элементом, сравнивая текущий элемент с тем, который следует за ним, меняя их значения при необходимости. Эти проходы по списку повторяются до тех пор, пока не останется необходимости в выполнении обменов во время прохода, что означает, что список стал полностью отсортированным. Алгоритм, который является сортировкой сравнений , назван так из-за способа, которым более крупные элементы «всплывают» наверх списка.

Этот простой алгоритм плохо работает в реальном мире и используется в основном как образовательный инструмент. Более эффективные алгоритмы, такие как быстрая сортировка , сортировка по времени или сортировка слиянием, используются библиотеками сортировки, встроенными в популярные языки программирования, такие как Python и Java. [2] [3] Однако, если параллельная обработка разрешена, пузырьковая сортировка сортируется за время O(n), что делает ее значительно быстрее параллельных реализаций сортировки вставкой или сортировки выбором, которые не так эффективно распараллеливаются. [ необходима цитата ]

История

Самое раннее описание алгоритма пузырьковой сортировки было в статье 1956 года математика и актуария Эдварда Гарри Френда [4] Сортировка в электронных компьютерных системах [5] , опубликованной в третьем выпуске третьего тома журнала Ассоциации вычислительной техники (ACM), как «Алгоритм сортировочного обмена». Френд описал основы алгоритма, и, хотя изначально его статья осталась незамеченной, несколько лет спустя он был заново открыт многими компьютерными учеными, включая Кеннета Э. Айверсона , который и придумал его нынешнее название.

Анализ

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

Производительность

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

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

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

Кролики и черепахи

Расстояние и направление, на которые должны перемещаться элементы во время сортировки, определяют производительность пузырьковой сортировки, поскольку элементы перемещаются в разных направлениях с разной скоростью. Элемент, который должен перемещаться к концу списка, может перемещаться быстро, поскольку он может принимать участие в последовательных обменах. Например, самый большой элемент в списке будет выигрывать каждый обмен, поэтому он перемещается в свою отсортированную позицию на первом проходе, даже если он начинается недалеко от начала. С другой стороны, элемент, который должен перемещаться к началу списка, не может перемещаться быстрее одного шага за проход, поэтому элементы перемещаются к началу очень медленно. Если самый маленький элемент находится в конце списка, потребуется несколько проходов, чтобы переместить его в начало. Это привело к тому, что эти типы элементов были названы кроликами и черепахами соответственно в честь персонажей басни Эзопа « Черепаха и заяц» .

Были предприняты различные попытки устранить черепах, чтобы улучшить скорость пузырьковой сортировки. Коктейльная сортировка — это двунаправленная пузырьковая сортировка, которая идет от начала к концу, а затем разворачивается, переходя от конца к началу. Она может довольно хорошо перемещать черепах, но сохраняет сложность наихудшего случая. Сортировка гребнем сравнивает элементы, разделенные большими промежутками, и может перемещать черепах чрезвычайно быстро, прежде чем перейти к меньшим и меньшим промежуткам, чтобы сгладить список. Ее средняя скорость сопоставима с более быстрыми алгоритмами, такими как быстрая сортировка .

Пошаговый пример

Возьмите массив чисел "5 1 4 2 8" и отсортируйте массив от наименьшего числа к наибольшему с помощью пузырьковой сортировки. На каждом шаге сравниваются элементы, выделенные жирным шрифтом . Потребуется три прохода;

Первый проход
( 5 1 4 2 8 ) → ( 1 5 4 2 8 ), Здесь алгоритм сравнивает первые два элемента и меняет их местами, поскольку 5 > 1.
( 1 5 4 2 8 ) → ( 1 4 5 2 8 ), Поменять местами, так как 5 > 4
( 1 4 5 2 8 ) → ( 1 4 2 5 8 ), Поменять местами, так как 5 > 2
( 1 4 2 5 8 ) → ( 1 4 2 5 8 ), Теперь, поскольку эти элементы уже расположены в порядке (8 > 5), алгоритм не меняет их местами.
Второй проход
( 1 4 2 5 8 ) → ( 1 4 2 5 8 )
( 1 4 2 5 8 ) → ( 1 2 4 5 8 ), Поменять местами, так как 4 > 2
( 1 2 4 5 8 ) → ( 1 2 4 5 8 )
( 1 2 4 5 8 ) → ( 1 2 4 5 8 )

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

Третий проход
( 1 2 4 5 8 ) → ( 1 2 4 5 8 )
( 1 2 4 5 8 ) → ( 1 2 4 5 8 )
( 1 2 4 5 8 ) → ( 1 2 4 5 8 )
( 1 2 4 5 8 ) → ( 1 2 4 5 8 )

Выполнение

Реализация псевдокода

В псевдокоде алгоритм можно выразить как (массив с отсчетом от 0):

procedure bubbleSort ( A : список сортируемых элементов ) n := length ( A ) repeat swapped := false for i : = 1 to n - 1 inclusive do { if эта пара не упорядочена } if A [ i - 1 ] > A [ i ] then { поменять их местами и запомнить, что что-то изменилось } swap ( A [ i - 1 ] , A [ i ]) swapped := true end if end for until not swapped end procedure                                         

Оптимизация пузырьковой сортировки

Алгоритм пузырьковой сортировки можно оптимизировать, наблюдая, что n -й проход находит n -й наибольший элемент и помещает его на свое последнее место. Таким образом, внутренний цикл может избежать просмотра последних n − 1 элементов при запуске в n -й раз:

procedure bubbleSort ( A : список сортируемых элементов ) n := length ( A ) repeat swapped := false for i := 1 to n - 1 inclusive do if A [ i - 1 ] > A [ i ] then swap ( A [ i - 1 ] , A [ i ]) swapped : = true end if end for n := n - 1 until not swapped end procedure                                                  

В более общем случае может случиться, что более одного элемента помещаются в их конечную позицию за один проход. В частности, после каждого прохода все элементы после последнего обмена сортируются и не нуждаются в повторной проверке. Это позволяет нам пропускать много элементов, что приводит к улучшению примерно на 50% количества сравнений в худшем случае (хотя улучшения количества обменов нет), и добавляет очень мало сложности, поскольку новый код включает в себя «переставленную» переменную:

Чтобы сделать это в псевдокоде, можно написать следующее:

procedure bubbleSort ( A : список сортируемых элементов ) n := length ( A ) repeat newn := 0 for i := 1 to n - 1 inclusive do if A [ i - 1 ] > A [ i ] then swap ( A [ i - 1 ] , A [ i ]) newn := i end if end for n : = newn until n 1 end procedure                                                 

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

Использовать

Сортировка пузырьком. Список был построен в декартовой системе координат, где каждая точка ( x , y ) указывала, что значение y хранится в индексе x . Затем список сортировался методом пузырьковой сортировки в соответствии со значением каждого пикселя. Обратите внимание, что наибольший конец сортируется первым, а меньшие элементы дольше перемещаются в правильные позиции.

Хотя сортировка пузырьком является одним из самых простых алгоритмов сортировки для понимания и реализации, его сложность O ( n 2 ) означает, что его эффективность резко снижается в списках, содержащих больше, чем небольшое количество элементов. Даже среди простых алгоритмов сортировки O ( n 2 ) такие алгоритмы, как сортировка вставкой, обычно значительно эффективнее.

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

Jargon File , который, как известно, называет bogosort «архетипичным [sic] извращенно ужасным алгоритмом», также называет пузырьковую сортировку «плохим обобщенным алгоритмом». [7] Дональд Кнут в своей книге «Искусство программирования » пришел к выводу, что «пузырьковая сортировка, похоже, не имеет ничего, что заслуживало бы ее рекомендовать, кроме броского названия и того факта, что она приводит к некоторым интересным теоретическим проблемам», некоторые из которых он затем обсуждает. [8]

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

Пузырьковая сортировка также плохо взаимодействует с современным оборудованием ЦП. Она производит как минимум вдвое больше записей, чем сортировка вставкой, вдвое больше промахов кэша и асимптотически больше неверных предсказаний ветвлений . [ требуется цитата ] Эксперименты Астрахана по сортировке строк в Java показывают, что пузырьковая сортировка примерно в пять раз быстрее сортировки вставкой и на 70% быстрее сортировки выбором . [6]

В компьютерной графике пузырьковая сортировка популярна из-за своей способности обнаруживать очень маленькую ошибку (например, перестановку всего двух элементов) в почти отсортированных массивах и исправлять ее с помощью линейной сложности (2 n ). Например, она используется в алгоритме заполнения многоугольника, где ограничивающие линии сортируются по своей координате x на определенной строке сканирования (линия, параллельная оси x ), а с увеличением y их порядок меняется (два элемента меняются местами) только на пересечениях двух линий. Пузырьковая сортировка — это устойчивый алгоритм сортировки, как и сортировка вставкой.

Вариации

Дебаты по поводу названия

Пузырьковую сортировку иногда называют «тонущей сортировкой». [9]

Например, Дональд Кнут описывает вставку значений в желаемое место или по направлению к нему как возможность «[значению] установиться на надлежащем уровне», и что «этот метод сортировки иногда называют методом просеивания или погружения ». [10]

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

  1. Большие значения могут рассматриваться как более тяжелые и, следовательно, постепенно опускаться в конец списка .
  2. Меньшие значения можно считать более легкими и, следовательно, постепенно подниматься к началу списка .

В популярной культуре

В интервью 2007 года бывший генеральный директор Google Эрик Шмидт спросил тогдашнего кандидата в президенты Барака Обаму о лучшем способе сортировки миллиона целых чисел ; Обама на мгновение задумался и ответил: «Я думаю, что пузырьковая сортировка — это неправильный способ». [11] [12]

Примечания

  1. ^ Кортези, Альдо (27 апреля 2007 г.). "Визуализация алгоритмов сортировки" . Получено 16 марта 2017 г.
  2. ^ "[JDK-6804124] (coll) Заменить "modified mergesort" в java.util.Arrays.sort на timsort - Java Bug System". bugs.openjdk.java.net . Получено 11.01.2020 .
  3. ^ Питерс, Тим (2002-07-20). "[Python-Dev] Сортировка" . Получено 2020-01-11 .
  4. ^ "Некролог ЭДВАРДА ФРЕНДА (2019) - Вашингтон, округ Колумбия - The Washington Post". Legacy.com .
  5. ^ Френд, Эдвард Х. (1956). «Сортировка в электронных вычислительных системах». Журнал ACM . 3 (3): 134–168. doi : 10.1145/320831.320833 . S2CID  16071355.
  6. ^ ab Astrachan, Owen (2003). «Пузырьковая сортировка: археологический алгоритмический анализ» (PDF) . ACM SIGCSE Bulletin . 35 (1): 1–5. doi :10.1145/792548.611918. ISSN  0097-8418.
  7. ^ "жаргон, узел: bogo-sort". www.jargon.net .
  8. ^ Дональд Кнут . Искусство программирования , том 3: Сортировка и поиск , второе издание. Addison-Wesley, 1998. ISBN 0-201-89685-0 . Страницы 106–110 раздела 5.2.2: Сортировка путем обмена. «Хотя методы, используемые в вычислениях [для анализа пузырьковой сортировки], поучительны, результаты разочаровывают, поскольку они говорят нам, что пузырьковая сортировка на самом деле совсем не хороша. По сравнению с прямой вставкой […], пузырьковая сортировка требует более сложной программы и занимает примерно в два раза больше времени!» (Цитата из первого издания, 1973 г.) 
  9. ^ Блэк, Пол Э. (24 августа 2009 г.). "пузырьковая сортировка". Словарь алгоритмов и структур данных . Национальный институт стандартов и технологий . Получено 1 октября 2014 г.
  10. ^ Кнут, Дональд (1997). Искусство программирования: Том 3: Поиск и сортировка . Addison-Wesley. стр. 80. ISBN 0201896850.
  11. ^ Лай Стирланд, Сара (14.11.2007). «Обама прошел собеседование в Google». Wired . Получено 27.10.2020 .
  12. Барак Обама, Эрик Шмидт (14 ноября 2007 г.). Барак Обама | Кандидаты в Google (видео) (YouTube). Маунтин-Вью, Калифорния 94043 Googleplex: выступления в Google. Событие состоится в 23:20. Архивировано из оригинала 7 сентября 2019 г. . Получено 18 сентября 2019 г. .{{cite AV media}}: CS1 maint: местоположение ( ссылка )

Ссылки

Внешние ссылки