Пузырьковая сортировка, алгоритм пузырьковой сортировки в последовательности массива
Содержание:
- Введение
- Введение
- 2. Обзор алгоритмов сортировки
- Сортировка пузырьком
- Метод пузырьковой сортировки в Паскале
- Проточная порометрия
- Как создать пузырьковую сортировку
- 1.2 Выбор программного обеспечения по реализации ИТ
- Сортировка слиянием (Merge sort)
- Подробный разбор пузырьковой сортировки
- Использовать
- 2.5 Сортировка Шелла
Введение
На данный момент существует множество алгоритмов сортировки данных. Зачастую выбор алгоритма решения задачи зависит от структуры сортируемых данных. В случае сортировки эта зависимость имеет большое значение, и методы сортировки обычно разделяют на две категории:
Сортировка массивов (внутренняя сортировка)
Сортировка последовательных файлов (внешняя сортировка)
При внутренней сортировке массивы располагаются в оперативной памяти ЭВМ, что обеспечивает быстрый произвольный доступ к данным.
При внешней сортировке файлы хранятся в более «медленной», но более вместительной внешней памяти, т.е. на запоминающих устройствах с механическим передвижением (магнитных дисках и других носителях).
Критериями оценки методов сортировки являются:
количество операций сравнения пар ключей
число перестановок элементов
экономное использование памяти
Цель курсовой работы:
систематизация, углубление и активное применение знаний по программированию в среде С++
рассмотреть основные алгоритмы сортировки
разработать, протестировать и проанализировать алгоритмы сортировки методом простых вставок и методом пузырька
Оценить производительность данных алгоритмов и сравнить их между собой по различным характеристикам
Актуальность:
С помощью ЭВМ можно решать самые разные задачи, в том числе автоматически выполнять требуемую сортировку данных. Сортировка может требоваться в различных ситуациях, например когда нужно отобразить визуально распределение данных. Для различных данных существуют определенные методы сортировок повышающие производительность и скорость сортировки именно для этого типа данных.
Рассматриваемые в данной работе сортировки методы сортировки являются относительно простыми, и хотя их эффективность ниже чем у более сложных и совершенных методов, но они так же имеют ряд преимуществ, и к тому же лежат в основе большинства других методов сортировки.
Новизна:
Рассматриваемые методы сортировок в силу своей простоты особенно хорошо подходят для изучения свойств большинства принципов сортировки, программы, основанные на данных методах легки для понимания и коротки (это также позволяет экономить память, занимаемую программой)
Так же важно отметить, что хотя сложные алгоритмы требуют меньшего числа операций, но эти операции являются более сложными. Поэтому при относительно малом количестве сортируемых элементов простые методы сортировки работают достаточно быстро
Введение
Общеизвестно, что самым быстрым методом сортировки данных в массивах является быстрая сортировка. Но существуют и другие классы сортировки, имеющие свои достоинства и недостатки. Например, сортировка выбором, сортировка вставками, сортировка слиянием, сортировка распределением, гибридная сортировка и параллельная сортировка. Кроме этих классов сортировок, есть ещё обменный способ сортировки, получивший название пузырьковой сортировки. В классе обменных сортировок есть более двенадцати видов различных сортировок, которые имеют тесную взаимосвязь с пузырьковой сортировкой. Упорядочивание (собственно, сортировка) выполняется путём многочисленного последовательного пересмотра данных массива и сравнения отдельных пар компонентов друг с другом. Если элементы, подлежащие сравнению, ещё не проходили сортировку по отношению друг к другу, то надо поменять их местами. Но проблема заключается в том, каким конкретно образом выбирать элементы массива в качестве пар для сравнения и по какому принципу обходить весь массив.
2. Обзор алгоритмов сортировки
Сортировка — это процесс перестановки объектов данного множества в определённом порядке. Цель сортировки — облегчить последующий поиск элементов в отсортированном множестве. Поэтому элементы сортировки присутствуют во многих задачах прикладного программирования.
Рассмотрим алгоритмы сортировки «на месте», то есть те алгоритмы в которых не используется копирование массива.
Удобной мерой эффективности алгоритмов сортировки «на месте» является число необходимых сравнений в ходе сортировки и число необходимых пересылок элементов.
Эффективные алгоритмы сортировки требуют порядка
сравнений, где N — число элементов, а С — число необходимых сравнений.
Мы рассмотрим простые методы сортировки, которые требуют число сравнений порядка
Методы сортировки «на месте» можно разбить на три основных класса:
сортировка выбором
сортировка вставками
сортировка обменом
В сортировке выбором выбирается элемент с наибольшим значением ключа и меняется местами с последним. Затем то же самое повторяется для s-1 элемента. Найденный элемент с наибольшим значением ключа меняется
Рисунок 1. Сортировка простым выбором
В сортировке включениями элементы разделяются на уже упорядоченную и неупорядоченную последовательности. В начале упорядоченная часть содержит только один элемент. Очередной элемент из начала неупорядоченной части вставляется на подходящее место в упорядоченную часть. При этом упорядоченная часть удлиняется на один элемент, а неупорядоченная — укорачивается. Сортировка заканчивается при исчезновении неупорядоченной части (рисунок 2).
Рисунок 2. Сортировка простыми включениями
Основная характеристика сортировки обменом — перестановка местами двух соседних элементов, если они расположены не так, как требует отсортированный массив.
Рисунок 3. Сортировка простым обменом
В рассмотренной классификации существуют разные алгоритмы. Они отличаются сложностью, быстротой выполнения, последовательностью операций.
Например:
сортировка вставками;
пузырьковая сортировка;
корневая сортировка;
пирамидальная сортировка;
сортировка слиянием;
быстрая сортировка;
сортировка Шелла и др.
Рассмотрим подробнее основные типы и виды сортировок (сначала простые сортировки затем более сложные).
Сортировка массива простым выбором
Метод основан на следующем правиле:
Выбирается элемент с наибольшим значением ключа
Он меняется местами с последним элементом arr . Затем эти операции повторяются с оставшимися первыми s-1 элементами, затем — с s-2 первыми элементами и т.д. до тех пор, пока не останется только первый элемент — наименьший. Пример сортировки методом простого выбора показан на рисунке 4:
Рисунок 4. Сортировка массива простым выбором
Эффективность сортировки простым выбором. Число сравнений ключей не зависит от начального порядка ключей. Операция сравнения выполняется в теле цикла с управляющей переменной k
и средним числом повторений size/2. Этот цикл, в свою очередь, находится в теле цикла с управляющей переменной L
и числом повторений size −1. Таким образом, число сравнений
С= (size −1) * size −1/2
Число пересылок, напротив, зависит от начального порядка ключей. Если принять, что операция сравнения в теле цикла по k
дает результат «истина» в половине случаев, то среднее число пересылок в этом цикле равно size/4. Цикл по L
, как указывалось выше, выполняется size −1 раз и в теле цикла выполняется три пересылки и цикл по k
. С учетом этого число пересылок:
М= (3+ size/4) * (size −1)
Получаем, что при сортировке простым выбором и число сравнений, и число пересылок пропорционально .
Сортировка пузырьком
Идея алгоритма очень простая. Идём по массиву чисел и проверяем порядок (следующее число должно быть больше и равно предыдущему), как только наткнулись на нарушение порядка, тут же обмениваем местами элементы, доходим до конца массива, после чего начинаем сначала.
Отсортируем массив {1, 5, 2, 7, 6, 3}
Идём по массиву, проверяем первое число и второе, они идут в порядке возрастания. Далее идёт нарушение порядка, меняем местами эти элементы
Продолжаем идти по массиву, 7 больше 5, а вот 6 меньше, так что обмениваем из местами
3 нарушает порядок, меняем местами с 7
Возвращаемся к началу массива и проделываем то же самое
void bubbleSort(int *a, size_t size) { size_t i, j; int tmp; for (i = 1; i < size; i++) { for (j = 1; j < size; j++) { if (a > a) { tmp = a; a = a; a = tmp; } } } }
Этот алгоритм всегда будет делать (n-1)2 шагов, независимо от входных данных. Даже если массив отсортирован, всё равно он будет пройден (n-1)2 раз. Более того, будут в очередной раз проверены уже отсортированные данные.
Пусть нужно отсортировать массив 1, 2, 4, 3
После того, как были поменяны местами элемента a и a нет больше необходимости проходить этот участок массива
Примем это во внимание и переделаем алгоритм
void bubbleSort2(int *a, size_t size) { size_t i, j; int tmp; for (i = 1; i < size; i++) { for (j = i; j > 0; j--) { if (a < a) { tmp = a; a = a; a = tmp; } } } }
Ещё одна реализация
void bubbleSort2b(int *a, size_t size) { size_t i, j; int tmp; for (i = 1; i < size; i++) { for (j = 1; j <= size-i; j++) { if (a < a) { tmp = a; a = a; a = tmp; } } } }
В данном случае будет уже вполовину меньше шагов, но всё равно остаётся проблема сортировки уже отсортированного массива: нужно сделать так, чтобы отсортированный массив функция просматривала один раз. Для этого введём переменную-флаг: он будет опущен (flag = 0), если массив отсортирован. Как только мы наткнёмся на нарушение порядка, то флаг будет поднят (flag = 1) и мы начнём сортировать массив как обычно.
void bubbleSort3(int *a, size_t size) { size_t i; int tmp; char flag; do { flag = 0; for (i = 1; i < size; i++) { if (a < a) { tmp = a; a = a; a = tmp; flag = 1; } } } while (flag); }
В этом случае сложность также порядка n2, но в случае отсортированного массива будет всего один проход.
Теперь усовершенствуем алгоритм. Напишем функцию общего вида, чтобы она сортировала массив типа void. Так как тип переменной не известен, то нужно будет дополнительно передавать размер одного элемента массива и функцию сравнения.
int intSort(const void *a, const void *b) { return *((int*)a) > *((int*)b); } void bubbleSort3g(void *a, size_t item, size_t size, int (*cmp)(const void*, const void*)) { size_t i; void *tmp = NULL; char flag; tmp = malloc(item); do { flag = 0; for (i = 1; i < size; i++) { if (cmp(((char*)a + i*item), ((char*)a + (i-1)*item))) { memcpy(tmp, ((char*)a + i*item), item); memcpy(((char*)a + i*item), ((char*)a + (i-1)*item), item); memcpy(((char*)a + (i-1)*item), tmp, item); flag = 1; } } } while (flag); free(tmp); }
Функция выглядит некрасиво – часто вычисляется адрес текущего и предыдущего элемента. Выделим отдельные переменные для этого.
void bubbleSort3gi(void *a, size_t item, size_t size, int (*cmp)(const void*, const void*)) { size_t i; void *tmp = NULL; void *prev, *cur; char flag; tmp = malloc(item); do { flag = 0; i = 1; prev = (char*)a; cur = (char*)prev + item; while (i < size) { if (cmp(cur, prev)) { memcpy(tmp, prev, item); memcpy(prev, cur, item); memcpy(cur, tmp, item); flag = 1; } i++; prev = (char*)prev + item; cur = (char*)cur + item; } } while (flag); free(tmp); }
Теперь с помощью этих функций можно сортировать массивы любого типа, например
void main() { int a = {1, 0, 9, 8, 7, 6, 2, 3, 4, 5}; int i; bubbleSort3gi(a, sizeof(int), 10, intSort); for (i = 0; i < 10; i++) { printf("%d ", a); } _getch(); }
Метод пузырьковой сортировки в Паскале
Замечание 1
Под сортировкой на языке Паскаль понимается упорядочение массива данных (как правило по возрастанию или по убыванию). Сортировка названа пузырьковой из-за аналогии с погруженными в воду вертикальным массивом. Массив — это вода, а его самые маленькие элементы являются пузырьками, которые стремятся всплыть вверх.
Алгоритм может быть представлен следующим образом:
-
Для выполнения процесса сортировки применяются два цикла, причём один цикл вложен в другой. Первый цикл применяется для формирования шагов, второй — под-шагов.
-
Основой алгоритма является сравнение двух элементов. К примеру, есть массив с десятью элементами. Элементы подлежат сравнению парами: 1 и 2, 2 и 3, 3 и 4 ,4 и 5 ,6 и 7 и так далее. Если при выполнении сравнения текущий элемент больше по величине чем следующий, то они меняются местами. К примеру, если первый элемент пять, а второй два, то они меняются местами.
-
Процесс сортировки пузырьковым методом подразделяется на шаги. Каждый шаг предполагает сравнение пары элементов. Итогом работы каждого шага является выстраивание самого большого элемента в конец массива. Таким образом после первого шага наибольший элемент массива окажется на последнем месте. При втором шаге действия выполняются по отношению ко всем элементам, исключая последний. Далее снова ищется наибольший элемент, и он перемещается опять в окончание массива, который в данный момент обрабатывается. И так процесс повторяется до полного окончания сортировки.
Приведём наглядный пример. Имеется массив, включающий в себя семь элементов: 2, 5, 11, 1, 7, 8, 3. Процесс сортировки изображён на рисунке 1.
Рисунок 1. Процесс сортировки. Автор24 — интернет-биржа студенческих работ
Далее сформируем собственно программу, реализующую данный алгоритм на языке Паскаль. Ниже приведён текст программы:
Замечание 2
Следует подчеркнуть, что элемент k нужен только для того, чтобы выполнить обмен местами двух элементов. Это объясняется тем, что Паскаль не имеет команды, которая смогла бы осуществить эту операцию. Это вынуждает формировать данную процедуру программным путём, вводя добавочный элемент для обмена.
Проточная порометрия
Перенос жидкости или газа через пористую
среду связан с параметрами этой среды.
Проточный метод изучения пористой
структуры основан на зависимости
удельной производительности от параметров
пористости. Расчет основан на уравнении
Пуазейля:
π r4∆P
V= ———— (4.25)
8ηδ
Модель упрощена до представления
мембраны как пористого тела с прямыми
цилиндрическими порами. Реальность
поры, т.е. ее извилистость, шероховатость,
анизотропность, учитывается эмпирическими
коэффициентами.
Рис. 4.67. Ячейка для определения среднего
размера пор в мембранах:1-верхняя
крышка;
2-уплотнителъное кольцо;
3-мембрана;
4-пористая подложка;
5-сетка; 6-нижняя крышка;
7-корпус ячейки;
8-уплотнительная прокладка (резиновое
кольцо)
Для стандартизации условий испытаний
используют ячейки с постоянной площадью
мембраны (рис.4.67).
На дно нижней крышки 6 помещают
металлическую сетку 5, затем подложку
4, испытываемую мембрану 3, уплотнительное
кольцо 2. Толщину мембраны предварительно
измеряют микрометром. Регулируют
давление сжатого воздуха и измеряют
производительность образца по жидкости,
заливаемой в ячейку.
Если бы поры в мембране были все одинаковы,
мы имели бы графическую зависимость
проницаемости от давления как на левой
части рис.4.68.
Сначала мембрана остается непроницаемой,
поскольку для продавливания жидкости
через любую пору необходимо некоторое
давление. ВеличинаРminопределяется смачиваемостью мембраны
жидкостью и размером самых больших пор.
Рис. 4.68. Зависимость удельной
производительности мембраны от
приложенного давления для идеальной
(слева) и реальной (справа) мембраны
В реальной мембране всегда существует
некоторое распределение пор по размерам,
поэтому кривая проницаемости сначала
имеет S-образный участок, а затем линейный.
Уравнение Пуазейля можно записать для
выражения количества жидкости, прошедшей
через мембрану площадью S с числом пор
N на единице площади за время t:
π r4∆PtSN
V= ————— (4.26)
8ηδ
В свою очередь N= П/ πr3,
где П — общая пористость мембраны, отсюда
8 ηδV8 ηG
r= ————— = ———— (4.27)
П∆PtSП∆P
Расчет, проведенный по данным линейного
участка зависимости на рис.4.68,
даст величину среднего размера пор
мембраны, что для мембран с узким
распределением пор является достаточной
характеристикой.
Принимаемые в методе допущения (о
цилиндричности и неизвилистости пор,
постоянстве сечения по всей длине
отдельных пор, равенстве общей и
эффективной, т.е. участвующей в транспорте
жидкости, пористости мембраны) вносят
определенные погрешности в оценку
среднего размера пор ультрафильтрационных
мембран. В частности, извилистость
реальных пор приводит при расчетах к
заниженным значениям их размеров. К
заниженным результатам приводит и
различие в общей и эффективной пористости
мембран вследствие ориентационной
упорядоченности пор.
К уменьшению величины эффективной
пористости по сравнению со значениями,
используемыми в расчетах, а, следовательно,
и занижению результатов, приводит
наличие в мембранах не участвующих в
течении пристенных слоев связанной
воды.
Толщина таких гидродинамически
неподвижных слоев составляет примерно
1 нм и, следовательно, вклад этого фактора
становится весьма ощутимым для
сравнительно тонкопористых мембран.С
другой стороны, асимметрия структуры
мембраны приводит к завышенным значениям
средних размеров пор. Это в определенной
мере нивелирует их занижение вследствие
неучета пристенных слоев воды, извилистости
и ориентационной упорядоченности пор.
Итак, в реальной мембране существуют
поры разного размера, поэтому зависимость
Gот ΔР на рисунке 4.67 имеетS-образный характер, т.е.
по мере повышения давления в работу
включаются все меньшие поры. Если
проводить ступенчатое по ΔР исследование,
то на каждый прирост ΔР наложится
прирост вG(рисунок 4.69).
Рис. 4.69. Графическая дифференциация
зависимости удельной производительности
мембраны от приложенного давления
В расчете будем использовать
модифицированные уравнения Пуазейля
и Лапласа:
π∙r4i—jt∙S∙Ni—j
Vi—j= ────────── ∙Pj(4.28)
8 ηδ
Pj=
2σ/ri—j(4.29)
Из них получим расчетные выражения для
rиN:
r∙δ
Ni—j= ──── ∙P3j∙ΔGi—j(4.30)
2πσ4
ri—j= 2σ/Pj(4.31)
Рассчитав для каждого интервала i-jэти две величины, получим информацию
для построения зависимостиNi—jдля каждого интервалаri—j(рис. 4.70).
Рис. 4.70. Зависимость «количество пор
– радиус пор»,
т.е. кривая распределения пор по размеру
Распределение пор по размеру является
наиболее объективной характеристикой
пористой мембраны.
Как создать пузырьковую сортировку
Вот что нам придется делать для создания пузырьковой сортировки:
- Создать два цикла , чтобы проходить по всем элементам массива раз ( это размер массива).
- Сравнивать ячейки массива, с помощью оператора ветвления .
- Менять местами значения ячеек.
В примере ниже мы предложили пользователю заполнить массив, который мы дальше отсортируем используя пузырьковую сортировку.
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, «rus»);
int digitals; // объявили массив на 10 ячеек
cout << «Введите 10 чисел для заполнения массива: » << endl;
for (int i = 0; i < 10; i++) {
cin >> digitals; // «читаем» элементы в массив
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 9; j++) {
if (digitals > digitals) {
int b = digitals; // создали дополнительную переменную
digitals = digitals; // меняем местами
digitals = b; // значения элементов
}
}
}
cout << «Массив в отсортированном виде: «;
for (int i = 0; i < 10; i++) {
cout << digitals << » «; // выводим элементы массива
}
system(«pause»);
return 0;
}
1 |
#include <iostream> usingnamespacestd; intmain(){ setlocale(LC_ALL,»rus»); intdigitals10;// объявили массив на 10 ячеек cout<<«Введите 10 чисел для заполнения массива: «<<endl; for(inti=;i<10;i++){ cin>>digitalsi;// «читаем» элементы в массив } for(inti=;i<10;i++){ for(intj=;j<9;j++){ if(digitalsj>digitalsj+1){ intb=digitalsj;// создали дополнительную переменную digitalsj=digitalsj+1;// меняем местами digitalsj+1=b;// значения элементов } } } cout<<«Массив в отсортированном виде: «; for(inti=;i<10;i++){ cout<<digitalsi<<» «;// выводим элементы массива } system(«pause»); return; } |
Давайте поподробнее разберем строки 16 — 24 (здесь находится пузырьковая сортировка)
- В строке 16: мы создали первый цикл .
- В строке 17: аналогично был создан второй, но уже вложенный цикл.
-
В строке 18: происходит сравнивание двух элементов.
- Если результат этого условия положительный, то мы меняем значение элементов.
- Если же результат отрицателен, то мы пропускаем этап смены значений.
- В строке 19: создали переменную , чтобы менять значения ячеек и местами.
Давайте посмотрим, что выведет программа выше при запуске:
sort_puzerek.cpp
Введите 10 чисел для заполнения массива:
5 3 6 2 7 0 2 8 9 10
Массив в отсортированном виде: 0 2 2 3 5 6 7 8 9 10
Process returned 0 (0x0) execution time : 0.005 s
Press any key to continue.
1.2 Выбор программного обеспечения по реализации ИТ
При написании программ для реализации сортировок массивов был использован язык программирования С++. Это один из широко используемых языков программирования, который можно использовать для написания программ, работающих в операционной среде Windows. Среда Borland C++ Builder 6- это сложный механизм, обеспечивающий высокоэффективную работу программиста
Интегрированная среда разработки C++ Builder представляет собой многооконную систему. Вид интегрированной среды разработки (интерфейс) может различаться в зависимости от настроек. Кроме стандартных окон, на экране могут присутствовать и другие окна, отображаемые при вызове соответствующих средств, например, Image Editor (Редактор изображений). Окна C++ Builder (но не главное) можно перемещать, убирать с экрана, а также изменять их размеры.
Несмотря на наличие многих окон, C++ Builder является одно-документной средой, т.е. позволяет одновременно работать только с одним приложением (проектом приложения). Название проекта приложения выводится в строке заголовка главного окна в верхней части экрана.
Если свернуть главное окно, то происходит минимизация всего интерфейса C++ Builder и, соответственно, всех открытых окон. При закрытии главного окна работа с C++ Builder прекращается.
Borland C++ Builder 6, вобрав в себя всё самое лучшее от предыдущих версий, предоставляет ряд новых возможностей. Так, например, стал более удобным и современным интерфейс среды программирования, создаваемые C++ Builder программы учитывают архитектуру современных процессоров, существенно расширены возможности отладчика.
Borland C++ Builder 6 может работать в среде операционных систем от Windows 95 до Windows XP. Особенных требований к компьютеру система не предъявляет, за исключением того, что процессор должен быть типа Pentium, оперативной памяти — не менее 32 Мбайт и достаточное количество свободной дисковой памяти.
Сортировка слиянием (Merge sort)
Алгоритм сортировки упорядочивает списки (или другие структуры данных, доступ к элементам которых можно получать только последовательно, например — потоки) в определённом порядке. Эта сортировка — хороший пример использования принципа «разделяй и властвуй». Сначала задача разбивается на несколько подзадач меньшего размера. Затем эти задачи решаются с помощью рекурсивного вызова или непосредственно, если их размер достаточно мал. Наконец, их решения комбинируются, и получается решение исходной задачи.
С исходным кодом алгоритма и его интерактивной презентацией вы сможете ознакомиться на исходном ресурсе.
Подробный разбор пузырьковой сортировки
Давайте разберем подробно как работает пузырьковая сортировка
Первая итереация (первый повтор алгоритма) меняет между собой 4 и 2 так как цифра два меньше чем четыре 2<4, повторюсь что алгоритм меняет значения между собой если, слева оно меньше чем справа. Далее происходит сверка между 4 и 3, и так как 3 меньше чем 4 (3<4) происходит обмен значениями. Потом проходит проверку между 4 и 8 и так как значение 4 меньше чем 8 то не происходит обмена, ведь уже и так всё на своих местах.
Далее сравнивается 8 и 1 и так как 1 меньше чем 8 (1<8) и оно не находиться слева то происходит обмен значениями.После это первый повтор алгоритма заканчивается, на анимации я выделил это зеленым фоном.
В итоге по окончанию работы алгоритма пузырьковой сортировки мы имеем следующий порядок числового массива: 2 3 4 1 8
и начинается второй повтор алгоритма.
Далее сравнивается 2 и 3 и так как два меньше чем три и оно находиться слева то просто идем дальше ничего не трогая. Также проверяем и 3 и 4 и тоже самое условие выполняется 3<4 и оно слева. Дальше проверяется 4 и 1 и тут мы видим что число 1<4 и не находиться слева, поэтому алгоритм меняет их местами. В крайний раз для второго повторения алгоритма проверяется 4 и 8, но тут всё в порядке, и мы дошли до конца начинаем третье повторение. Итоги для второго повторения такие : 2 3 1 4 8
Третье повторение пузырькового алгоритма начинается с сравнения 2 и 3, тут алгоритм проверяет что 2<3 и 2 находиться слева и оставляет их в покое и идет дальше. Сравнение же 3 и 1 показывает что 1 то меньше чем три, но почему то не слева и меняет их местами. Далее идет сравнение 3 и 4, тут всё в порядке и так далее до сравнения 4 и 8.
После этого получается следующий результат: 2 1 3 4 8
Как мы видим почти все цифры уже на своих местах и в порядке возрастания! Осталось только в последнем повторении пузырькового алгоритма поменять местами 2 и 1 и всё. После того как алгоритм закончил свою работу и проверил что цифры больше нельзя поменять местами он перестает работать с таким вот результатом: 1 2 3 4 8
Использовать
Пузырьковая сортировка — алгоритм сортировки, который непрерывно просматривает список, меняя местами элементы, пока они не появятся в правильном порядке. Список был построен в декартовой системе координат, где каждая точка ( x , y ) указывает, что значение y хранится в индексе x . Затем список будет отсортирован пузырьковой сортировкой по значению каждого пикселя
Обратите внимание, что сначала сортируется самый большой конец, а меньшим элементам требуется больше времени, чтобы переместиться в правильное положение.
Хотя пузырьковая сортировка является одним из самых простых алгоритмов сортировки для понимания и реализации, ее сложность O ( n 2 ) означает, что ее эффективность резко снижается в списках, состоящих из более чем небольшого числа элементов. Даже среди простых алгоритмов сортировки O ( n 2 ) такие алгоритмы, как сортировка вставкой , обычно значительно более эффективны.
Из-за своей простоты пузырьковая сортировка часто используется для знакомства с концепцией алгоритма или алгоритма сортировки для начинающих студентов- информатиков . Тем не менее, некоторые исследователи, такие как Оуэн Астрахан , пошли на многое, чтобы осудить пузырьковую сортировку и ее неизменную популярность в образовании по информатике, рекомендуя даже не преподавать ее.
Жаргон Файл , который лихо звонков bogosort «архетипический извращенно ужасный алгоритм», также вызывает пузырьковую сортировку «общий плохой алгоритм». Дональд Кнут в своей книге «Искусство компьютерного программирования» пришел к выводу, что «пузырьковой сортировке, похоже, нечего рекомендовать, кроме броского названия и того факта, что она приводит к некоторым интересным теоретическим проблемам», некоторые из которых он затем обсуждает.
Пузырьковая сортировка асимптотически эквивалентна по времени работы сортировке вставкой в худшем случае, но эти два алгоритма сильно различаются по количеству необходимых перестановок. Экспериментальные результаты, такие как результаты Astrachan, также показали, что сортировка вставкой работает значительно лучше даже в случайных списках. По этим причинам многие современные учебники алгоритмов избегают использования алгоритма пузырьковой сортировки в пользу сортировки вставкой.
Пузырьковая сортировка также плохо взаимодействует с современным оборудованием ЦП. Он производит как минимум вдвое больше записей, чем сортировка вставкой, вдвое больше промахов в кеш и асимптотически больше ошибочных прогнозов переходов . Эксперименты с сортировкой строк Astrachan в Java показывают, что пузырьковая сортировка примерно в пять раз быстрее сортировки вставкой и на 70% быстрее сортировки по выбору .
В компьютерной графике пузырьковая сортировка популярна благодаря своей способности обнаруживать очень маленькую ошибку (например, замену всего двух элементов) в почти отсортированных массивах и исправлять ее с линейной сложностью (2 n ). Например, он используется в алгоритме заполнения многоугольника, где ограничивающие линии сортируются по их координате x в определенной строке сканирования (линия, параллельная оси x ), а с увеличением y их порядок изменяется (два элемента меняются местами) только при пересечения двух линий. Пузырьковая сортировка — это стабильный алгоритм сортировки, как и сортировка вставкой.
2.5 Сортировка Шелла
На рисунке 9 продемонстрирована сортировка методом Шелла:
Рисунок 9. Сортировка Шелла
На первом проходе отдельно группируются и сортируются все элементы, отстоящие друг от друга на четыре позиции. Этот процесс называется 4-сортировкой. В нашем примере из восьми элементов каждая группа содержит ровно два элемента. После этого элементы вновь объединяются в группы с элементами, отстоящими друг от друга на две позиции, и сортируются заново. Этот процесс называется 2-сортировкой. Наконец на третьем проходе все элементы сортируются обычной 1-сортировкой включением.
На каждом шаге в сортировке участвует либо сравнительно мало элементов, либо они уже довольно хорошо упорядочены и требуют относительно мало перестановок. Очевидно, что этот метод дает упорядоченный массив, и также совершенно ясно, что каждый проход будет использовать результаты предыдущего прохода, поскольку каждая i-сортировка объединяет две группы, рассортированные предыдущей 2i-сортировкой. Также ясно, что приемлема любая последовательность приращений, лишь бы последнее было равно 1, так как в худшем случае вся работа будет выполняться на последнем проходе. Однако менее очевидно, что метод убывающего приращения дает даже лучшие результаты, когда приращения не являются степенями двойки. Таким образом, программа разрабатывается вне связи с конкретной последовательностью приращений. Все t приращений обозначаются через
h1, h2,…, hn с условиями ht=1, hi+1 < hi.
Каждая h-сортировка программируется как сортировка простыми включениями, при этом, для того чтобы условие окончания поиска места включения было простым, используется барьер. Ясно, что каждая h-сортировка требует собственного барьера и что программа должна определять его место как можно проще.