Сортировка пузырьком
Сортировка пузырько́м (англ. bubble sort), сортиро́вка простыми обменами, метод сортировки обменами — один из алгоритмов сортировки. По сравнению с другими алгоритмами считается простейшим для понимания и реализации. Эффективен для массивов небольшого размера. — размер массива, количество элементов массива. Сложность алгоритма: . Алгоритм считается учебным, на практике (вне учебной литературы) не применяется (на практике применяются более эффективные (совершенные) алгоритмы). Лежит в основе некоторых более эффективных алгоритмов, например, алгоритма шейкерной сортировки, алгоритма пирамидальной сортировки и алгоритма быстрой сортировки. АлгоритмВыполняется некоторое количество проходов по массиву — начиная от начала массива, перебираются пары соседних элементов массива. Если 1-й элемент пары больше 2-го, элементы переставляются (выполняется обмен). Пары элементов массива перебираются (проходы по массиву повторяются) либо раз, либо до тех пор, пока на очередном проходе не обнаружится, что более не требуется выполнять перестановки (обмены) (массив отсортирован). При каждом проходе алгоритма по внутреннему циклу очередной наибольший элемент массива ставится на своё место в конце массива рядом с предыдущим «наибольшим элементом», а наименьший элемент перемещается на одну позицию к началу массива (как бы «всплывает» до нужной позиции, как пузырёк в воде — откуда и название алгоритма). РеализацияСложность: . Для наихудшего случая верно следующее.
Для наилучшего случая верно следующее.
Особенность алгоритма. После 1-го прохода (завершения внутреннего цикла) максимальный элемент массива находится в позиции номер . После 2-го прохода следующий по значению максимальный элемент находится в позиции номер . И так далее. Для каждого следующего прохода по сравнению с текущим проходом количество обрабатываемых элементов меньше на единицу. Нет необходимости каждый проход перебирать все пары элементов («обходить» весь массив) от начала массива к концу массива. Если (массив содержит один элемент), то не требуется сортировать массив. Если , для сортировки массива требуется выполнить не более итераций внешнего цикла. Некоторые реализации выполняют тело внешнего цикла раз и не учитывают (не отслеживают) информацию о том, были ли или не были перестановки на каждой итерации цикла. Если на вход подаётся частично отсортированный массив, то можно уменьшить количество проходов по массиву — ввести индикатор произошедших перестановок (флажок F). Перед каждым проходом по внутреннему циклу флажок F сбрасывается в 0, а после перестановки — устанавливается в 1. Если после выполнения внутреннего цикла флажок F равен 0, то при выполнении внутреннего цикла перестановок не было; то есть, массив отсортирован и можно досрочно выйти из программы сортировки. Псевдокод улучшенного алгоритма — алгоритма с проверкой, были ли перестановки во внутреннем цикле. На входе: массив — массив, содержащий элементов. 1-й элемент обозначен как , последний — как . ЦИКЛ ДЛЯ J=1 ДО n-1 ШАГ 1 FOR J=1 TO n-1 STEP 1
F=0 F=0
ЦИКЛ ДЛЯ I=0 ДО n-1-J ШАГ 1 FOR I=0 TO n-1-J STEP 1
ЕСЛИ A[I] > A[I+1] ТО ОБМЕН A[I],A[I+1]:F=1 IF A[I]>A[I+1] THEN SWAP A[I],A[I+1]:F=1
СЛЕДУЮЩЕЕ I NEXT I
ЕСЛИ F=0 ТО ВЫХОД ИЗ ЦИКЛА IF F=0 THEN EXIT FOR
СЛЕДУЮЩЕЕ J NEXT J
Чтобы досрочно завершить программу сортировки, требуется выполнить один (избыточный) проход без обменов. Для наихудшего (не улучшаемого) случая верно следующее.
Для наилучшего случая верно следующее.
На программно-аппаратном комплексе, выполняющем сравнение примерно 3,4 мкс и выполняющем перестановку примерно 2,3 мкс, время сортировки 10 000 коротких целых чисел реализацией алгоритма сортировки выбором составило примерно 40 с, ещё более улучшенной сортировкой пузырьком — примерно 30 с, а быстрой сортировкой — примерно 0,027 с. больше, чем у сортировки слиянием. Но при малых разница не очень большая, а программный код сравнительно прост. Поэтому вполне допустимо применение сортировки пузырьком для множества задач с массивами малой размерности на простаивающих и малозагруженных машинах. Если во внутреннем цикле просматривать массив не от начала к концу, а поочерёдно то от начала к концу, то от конца к началу, то получится алгоритм, называемый алгоритмом сортировки перемешиванием (шейкерной сортировки). Сложность полученного алгоритма равна , не меньше сложности исходного алгоритма. При сортировке пузырьком при каждом проходе по внутреннему циклу можно добавить определение очередного минимального элемента и помещение его в начало массива. То есть, можно объединить алгоритм сортировки пузырьком и алгоритм сортировки выбором. При этом количество проходов по внутреннему циклу уменьшится вдвое, но более чем вдвое увеличится количество сравнений и после каждого прохода по внутреннему циклу добавится одна перестановка. Псевдокод устойчивой реализации объединённого алгоритма сортировки пузырьком и сортировки выбором: Пример работы алгоритмаИспользуя алгоритм сортировки пузырьком, отсортируем по возрастанию массив чисел, равный «5 1 4 2 8». Выделены те элементы, которые сравниваются на текущем этапе. Первый проход:
Второй проход:
Теперь массив полностью отсортирован, но алгоритму это неизвестно. Необходимо сделать полный проход, чтобы определить, что перестановок (обменов) элементов не было. Третий проход:
Теперь массив отсортирован и алгоритм может быть завершён. Пример реализацииПример реализации алгоритма сортировки пузырьком на языке Java: public void sort(int[] data) {
int n = data.length;
for (int j = 1; j < n; j++) {
boolean isSorted = true;
for (int i = 0; i < n - j; i++) {
if (data[i] > data[i + 1]) {
int tmp = data[i];
data[i] = data[i + 1];
data[i + 1] = tmp;
isSorted = false;
}
}
if (isSorted) {
break;
}
}
}
Ссылки
|