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

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

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

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

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

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

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

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

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

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

Споры по поводу имени

Сортировку пузырьков иногда называют «тонущей сортировкой».

Например, в книге Дональда Кнута « Искусство компьютерного программирования» , том 3: Сортировка и поиск, он заявляет в разделе 5.2.1 «Сортировка вставкой», что «устанавливается на свой надлежащий уровень» и что этот метод сортировки имеет иногда называют техникой просеивания или погружения .

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

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

Варианты алгоритма

Сорт коктейлей

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

Идея сортировки коктейлей состоит в чередовании направления маршрута. Получается несколько более быстрая сортировка, с одной стороны, потому что она требует меньшего количества сравнений, с другой стороны, потому что она перечитывает самые последние данные при изменении направления (поэтому они все еще находятся в кэш-памяти ). Однако количество обменов, которые необходимо произвести, идентично (см. Выше). Таким образом, время выполнения всегда пропорционально n 2 и, следовательно, посредственно.

Три прыжка вниз

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

tri_jump_down(Tableau T)
   pour i allant de taille de T - 1 à 1
       pour j allant de 0 à i - 1
           si T < T
               échanger(T, T)

Сортировка combsort

Вариант пузырьковой сортировки, называемый гребенчатой ​​сортировкой ( combsort ), был разработан в 1980 году Влодзимежем Добосевичем и вновь появился в апреле 1991 года в журнале Byte Magazine . Он исправляет главный недостаток пузырьковой сортировки, которой являются «черепахи», и делает алгоритм столь же эффективным, как и быстрая сортировка .

Как создать пузырьковую сортировку

Вот что нам придется делать для создания пузырьковой сортировки:

  • Создать два цикла , чтобы проходить по всем элементам массива раз ( это размер массива).
  • Сравнивать ячейки массива, с помощью оператора ветвления .
  • Менять местами значения ячеек.

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

#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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

#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 (здесь находится пузырьковая сортировка)

  1. В строке 16: мы создали первый цикл .
  2. В строке 17: аналогично был создан второй, но уже вложенный цикл.
  3. В строке 18: происходит сравнивание двух элементов.

    • Если  результат этого условия положительный, то мы меняем значение элементов.
    • Если же результат отрицателен, то мы пропускаем этап смены значений.
  4. В строке 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.

Пузырьковая сортировка и её улучшения

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

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

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

void BubbleSort(vector<int>& values) {
  for (size_t idx_i = 0; idx_i + 1 < values.size(); ++idx_i) {
    for (size_t idx_j = 0; idx_j + 1 < values.size() - idx_i; ++idx_j) {
      if (values < values) {
        swap(values, values);
      }
    }
  }
}

Сортировка перемешиванием (шейкерная сортировка)

Шейкерная сортировка отличается от пузырьковой тем, что она двунаправленная: алгоритм перемещается не строго слева направо, а сначала слева направо, затем справа налево.

void ShakerSort(vector<int>& values) {
  if (values.empty()) {
    return;
  }
  int left = 0;
  int right = values.size() - 1;
  while (left <= right) {
    for (int i = right; i > left; --i) {
      if (values > values) {
        swap(values, values);
      }
    }
    ++left;
    for (int i = left; i < right; ++i) {
      if (values > values) {
        swap(values, values);
      }
    }
    --right;
  }
}

Сортировка расчёской

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

Первоначальный разрыв нужно выбирать не случайным образом, а с учётом специальной величины — фактора уменьшения, оптимальное значение которого равно 1,247. Сначала расстояние между элементами будет равняться размеру массива, поделённому на 1,247; на каждом последующем шаге расстояние будет снова делиться на фактор уменьшения — и так до окончания работы алгоритма.

void CombSort(vector<int>& values) {
  const double factor = 1.247; // Фактор уменьшения
  double step = values.size() - 1;

  while (step >= 1) {
    for (int i = 0; i + step < values.size(); ++i) {
      if (values > values) {
        swap(values, values);
      }
    }
    step /= factor;
  }
  // сортировка пузырьком
  for (size_t idx_i = 0; idx_i + 1 < values.size(); ++idx_i) {
    for (size_t idx_j = 0; idx_j + 1 < values.size() - idx_i; ++idx_j) {
      if (values < values) {
        swap(values, values);
      }
    }
  }
}

Как улучшить пузырьковую сортировку

Ниже вы можете видеть оптимизированную версию пузырьковой сортировки.

for (int i = 0; i < 10; i++) {
bool flag = true;
for (int j = 0; j < 10 — (i + 1); j++) {
if (digitals > digitals) {
flag = false;
swap (digitals, digitals);
}
}
if (flag) {
break;
}
}

1
2
3
4
5
6
7
8
9
10
11
12

for(inti=;i<10;i++){

boolflag=true;

for(intj=;j<10-(i+1);j++){

if(digitalsj>digitalsj+1){

flag=false;

swap(digitalsj,digitalsj+1);

}

}

if(flag){

break;

}

}

Давайте посмотрим, что мы сделали для ее оптимизации:

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

Для этого в строке 5: чтобы пузырьковая сортировка останавливалась (когда массив уже стал отсортирован), мы объявили булеву переменную (ее обычно называют флаг или флажок). Еще при ее инициализации мы поместили значение , но она меняется на:

false, если результат условия в строке 4: положительный.

А в строке 9: чтобы мы могли выйти из алгоритма мы проверяем:

  • Если булева переменная равна , значит массив уже полностью отсортирован и можно выйти. Для этого используем оператор .
  • Если же значение равно , то продолжаем сортировать массив.

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

int b = digitals;
digitals = digitals;
digitals = b;

1
2
3

intb=digitalsj;

digitalsj=digitalsj+1;

digitalsj+1=b;

Использовать ее необязательно, потому что она не сделает код быстрее. Но как мы сказали выше, кода станет меньше.

Сортировка массива методом пузырька- решение на C++

Сортировка массива методом пузырька- решение на C++

Алгоритм пузырьковой сортировки — это довольно простой в реализации алгоритм для сортировки массивов. Можно встретить и другие названия: пузырьковая сортировка, Bubble sort или сортировка простыми обменами — но все они будут обозночать один и тот же алгоритм. Назван так, потому что большее или меньшее значение «всплывает» (сдвигается) к краю массива после каждой итерации, это будет видно в примере.

Исходный код на языке C++

/*
* Ввести целочисленный массив из N целых чисел.
* Отсортировать этот массив по возрастанию методом пузырька
*/
#include &lt;iostream&gt;

using namespace std;

int main()
{
int *arr; // указатель для выделения памяти под массив
int size; // размер массива

// Ввод количества элементов массива
cout &lt;&lt; «n = «;
cin &gt;&gt; size;

if (size &lt;= 0) {
// Размер масива должен быть положитлеьным
cerr &lt;&lt; «Invalid size» &lt;&lt; endl;
return 1;
}

arr = new int; // выделение памяти под массив

// заполнение массива
for (int i = 0; i &lt; size; i++) {
cout &lt;&lt; «arr = «;
cin &gt;&gt; arr;
}

int temp; // временная переменная для обмена элементов местами

// Сортировка массива пузырьком
for (int i = 0; i &lt; size — 1; i++) {
for (int j = 0; j &lt; size — i — 1; j++) {
if (arr &gt; arr) {
// меняем элементы местами
temp = arr;
arr = arr;
arr = temp;
}
}
}

// Вывод отсортированного массива на экран
for (int i = 0; i &lt; size; i++) {
cout &lt;&lt; arr &lt;&lt; » «;
}
cout &lt;&lt; endl;

delete [] arr; // освобождение памяти;

return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

/*
* Ввести целочисленный массив из N целых чисел.
* Отсортировать этот массив по возрастанию методом пузырька
*/
#include &lt;iostream&gt;
 

using namespacestd;

intmain()

{

int*arr;// указатель для выделения памяти под массив

intsize;// размер массива

// Ввод количества элементов массива

cout&lt;&lt;»n = «;

cin&gt;&gt;size;

if(size&lt;=){

// Размер масива должен быть положитлеьным

cerr&lt;&lt;»Invalid size»&lt;&lt;endl;

return1;

}

arr=newintsize;// выделение памяти под массив

// заполнение массива

for(inti=;i&lt;size;i++){

cout&lt;&lt;»arr = «;

cin&gt;&gt;arri;

}

inttemp;// временная переменная для обмена элементов местами

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

for(inti=;i&lt;size-1;i++){

for(intj=;j&lt;size-i-1;j++){

if(arrj&gt;arrj+1){

// меняем элементы местами

temp=arrj;

arrj=arrj+1;

arrj+1=temp;

}

}

}

// Вывод отсортированного массива на экран

for(inti=;i&lt;size;i++){

cout&lt;&lt;arri&lt;&lt;» «;

}

cout&lt;&lt;endl;

deletearr;// освобождение памяти;

return;

}

Модификации[править]

Сортировка чет-нечетправить

Сортировка чет-нечет (англ. odd-even sort) — модификация пузырьковой сортировки, основанная на сравнении элементов стоящих на четных и нечетных позициях независимо друг от друга. Сложность — .
Псевдокод указан ниже:

function oddEvenSort(a):
  for i = 0 to n - 1 
    if i mod 2 == 0
      for j = 2 to n - 1 step 2
        if a < a
          swap(a, a)  
    else      
      for j = 1 to n - 1 step 2
        if a < a
          swap(a, a)

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

Сортировка расческойправить

Сортировка расческой (англ. comb sort) — модификация пузырьковой сортировки, основанной на сравнении элементов на расстоянии. Сложность — , но стремится к . Является самой быстрой квадратичной сортировкой. Недостаток — она неустойчива. Псевдокод указан ниже:

function combSort(a):
  k = 1.3
  jump = n
  bool swapped = true
  while jump > 1 and swapped
    if jump > 1
      jump /= k
    swapped = false
    for i = 0 to size - jump - 1
      if a < a
        swap(a, a)
        swapped = true

Пояснения: Изначально расстояние между сравниваемыми элементами равно , где — оптимальное число для этого алгоритма. Сортируем массив по этому расстоянию, потом уменьшаем его по этому же правилу. Когда расстояние между сравниваемыми элементами достигает единицы, массив досортировывается обычным пузырьком.

Сортировка перемешиваниемправить

Сортировка перемешиванием (англ. cocktail sort), также известная как Шейкерная сортировка — разновидность пузырьковой сортировки, сортирующая массив в двух направлениях на каждой итерации. В среднем, сортировка перемешиванием работает в два раза быстрее пузырька. Сложность — , но стремится она к , где — максимальное расстояние элемента в неотсортированном массиве от его позиции в отсортированном массиве. Псевдокод указан ниже:

function shakerSort(a):
  begin = -1
  end = n - 2
  while swapped
    swapped = false   
    begin++
    for i = begin to end 
      if a > a 
        swap(a, a)
        swapped = true    
    if !swapped
      break    
    swapped = false 
    end--
    for i = end downto begin
      if a > a 
        swap(a, a)
        swapped = true

Не спеша, эффективно и правильно – путь разработки. Часть 2. Теория

Черновой вариант книги Никиты Зайцева, a.k.a.WildHare. Разработкой на платформе 1С автор занимается с 1996-го года, специализация — большие и по-хорошему страшные системы. Квалификация “Эксперт”, несколько успешных проектов класса “сверхтяжелая”. Успешные проекты ЦКТП. Четыре года работал в самой “1С”, из них два с половиной архитектором и ведущим разработчиком облачной Технологии 1cFresh. Ну — и так далее. Не хвастовства ради, а понимания для. Текст написан не фантазером-теоретиком, а экспертом, у которого за плечами почти двадцать три года инженерной практики на больших проектах.

В чём хитрость сортировки расчёской

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

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

Опытным путём программисты установили оптимальное расстояние между элементами — это длина массива, поделённая на 1,247 (понятное дело, расстояние нужно округлить до целого числа). С этим числом алгоритм работает быстрее всего.

Сложность алгоритмов

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

Время выполнения описывает, сколько операций должен выполнить алгоритм до его завершения. Пространственная сложность — сколько места должно быть выделено для запуска. Например, если алгоритм принимает список размером n и по какой-то причине создает новый с таким же для каждого элемента в n, то требуется пространство n2 . Кроме того, иногда полезно знать устойчивость выполнения. Алгоритм стабилен, если он сохраняет исходный порядок элементов с одинаковыми значениями.

Таблица сложности алгоритмов:

Алгоритм Пространственная сложность Худший случай Средний случай Лучший случай Стабильный
Сортировка слиянием О (n) O (n lоg n) O (n log n) O (n lоg n) Да
Сортировка вставками О (1) O (n 2 ) O (n 2 ) O (n) Да
Сортировка пузырьком О (1) O (n 2 ) O (n 2 ) O (n) Да
Быстрая lоg n O (n 2 ) O (n log n) O (n lоg n) Обычно нет*
Сортировка блоками O (1) O (n lоg n) O (n log n) O (n lоg n) Нет
Сортировка подсчетом O (k+n) O (k+n) O (k+n) O (k+n) Да

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

Анализ

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

Представление

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

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

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

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

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

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

Возьмите массив чисел «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 )

Что такое сортировка выбора

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

Пример таков.

7  8  5  4  9  2

Мы принимаем минимальное значение как 7. Мы проверяем значение 8. Это не меньше 7. Итак, мы проверяем 5. Это меньше 7. Теперь минимальное значение равно 5. Теперь рассмотрим 4. Это меньше, чем минимальное значение (5). Поэтому теперь минимальное значение равно 4. Далее рассмотрим число 9. Оно не меньше текущего минимального значения (4). Итак, мы переходим к следующему элементу, который равен 2. Он меньше текущего минимального значения (4). Теперь минимальное значение равно 2. Мы можем поменять местами 7 и 2. Теперь список выглядит следующим образом.

2  8  5  4  9  7

Теперь 2 уже отсортировано, и это самое маленькое число в списке. Остальное — несортированный список. Теперь мы должны отсортировать 8 5 4 9 7. Мы рассматриваем 8 как минимальное значение. Значение 5 меньше минимального значения (8). Итак, теперь минимальное значение равно 5. Тогда значение 4 меньше минимального значения. Теперь минимальное значение равно 4. Тогда 9 не меньше минимального значения 4. Поэтому мы рассмотрим следующий элемент 7. Это не меньше минимального значения 4. Теперь минимальное значение равно 4. Поэтому мы меняем значение 4 и значение 8 (1улица элемент в списке). Теперь список выглядит следующим образом.

2 4  5  8  9  7

Теперь 2 и 4 отсортированы. Мы можем отсортировать 5 8 9 7. Мы считаем 5 минимальным значением и повторяем описанный выше процесс и получаем отсортированный список в конце.

Программа упорядочения строк в алфавитном порядке[править]

 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #define N 100
 #define M 30
 int main(int argc, char* argv[]) {
    char aN];
    int n, i;
    scanf("%d", &n);
    for (i=; i<n; i++)
       scanf("%s", &ai]);
    qsort(a, n, sizeof(charM]), (int (*)(const void *,const  void *)) strcmp);
    for (i=; i<n; i++)
       printf("%s\n", ai]);
    return ;
 }

Обратите внимание на сложное приведение типов.

Функция strcmp, объявленная в файле string.h имеет следующий прототип:

int strcmp(const char*, const char*);

То есть функция получает два аргумента — указатели на кусочки памяти, где хранятся элементы типа char,
то есть два массива символов, которые не могут быть изменены внутри функции strcmp (запрет на изменение задается с помощью модификатора const).

В то же время в качестве четвертого элемента функция qsort хотела бы иметь функцию типа

int cmp(const void*, const void*);

В языке Си можно осуществлять приведение типов являющихся типами функции. В данном примере тип

int (*)(const char*, const char*); // функция, получающая два элемента типа 'const char *' и возвращающая элемент типа 'int' 

приводится к типу

int (*)(const void*, const void*); // функция, получающая два элемента типа 'const void *' и возвращающая элемент типа 'int'

Как можно улучшить шейкер сортировку

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

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

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

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

Ниже, находится оптимизированная версия шейкер сортировки:

bool sort_or_not = true;
int right = n — 1; // n — размер массива
int left = 1;
do {
bool sort_or_not = true;
for (int i = left; i <= right; i++) {
if (chisla > chisla) {
swap (chisla, chisla);
sort_or_not = false;
}
}
right—;
for (int i = right; i >= left; i—) {
if (chisla < chisla) {
swap (chisla, chisla);
sort_or_not = false;
}
}
left++;
} while (sort_or_not == false);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

boolsort_or_not=true;

intright=n-1;// n — размер массива

intleft=1;

do{

boolsort_or_not=true;

for(inti=left;i<=right;i++){

if(chislai-1>chislai){

swap(chislai-1,chislai);

sort_or_not=false;

}

}

right—;

for(inti=right;i>=left;i—){

if(chislai<chislai-1){

swap(chislai,chislai-1);

sort_or_not=false;

}

}

left++;

}while(sort_or_not==false);

Таблица 1: Сортировка пузырьком в однопоточном режиме

1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14
2 1 3 4 5 6 7 8 9 10 11 12 13 14
2 3 1 4 5 6 7 8 9 10 11 12 13 14
2 3 4 1 5 6 7 8 9 10 11 12 13 14
2 3 4 5 1 6 7 8 9 10 11 12 13 14
2 3 4 5 6 1 7 8 9 10 11 12 13 14
2 3 4 5 6 7 1 8 9 10 11 12 13 14
2 3 4 5 6 7 8 1 9 10 11 12 13 14
2 3 4 5 6 7 8 9 1 10 11 12 13 14
2 3 4 5 6 7 8 9 10 1 11 12 13 14
2 3 4 5 6 7 8 9 10 11 1 12 13 14
2 3 4 5 6 7 8 9 10 11 12 1 13 14
2 3 4 5 6 7 8 9 10 11 12 13 1 14
2 3 4 5 6 7 8 9 10 11 12 13 14 1
2 3 4 5 6 7 8 9 10 11 12 13 14
3 2 4 5 6 7 8 9 10 11 12 13 14 1
3 4 2 5 6 7 8 9 10 11 12 13 14 1
3 4 5 2 6 7 8 9 10 11 12 13 14 1
3 4 5 6 2 7 8 9 10 11 12 13 14 1
3 4 5 6 7 2 8 9 10 11 12 13 14 1
3 4 5 6 7 8 2 9 10 11 12 13 14 1
3 4 5 6 7 8 9 2 10 11 12 13 14 1
3 4 5 6 7 8 9 10 2 11 12 13 14 1
3 4 5 6 7 8 9 10 11 2 12 13 14 1
3 4 5 6 7 8 9 10 11 12 2 13 14 1
3 4 5 6 7 8 9 10 11 12 13 2 14 1
3 4 5 6 7 8 9 10 11 12 13 14 2 1
3 4 5 6 7 8 9 10 11 12 13 14
4 3 5 6 7 8 9 10 11 12 13 14 2 1
4 5 3 6 7 8 9 10 11 12 13 14 2 1
4 5 6 3 7 8 9 10 11 12 13 14 2 1
4 5 6 7 3 8 9 10 11 12 13 14 2 1
4 5 6 7 8 3 9 10 11 12 13 14 2 1
4 5 6 7 8 9 3 10 11 12 13 14 2 1
4 5 6 7 8 9 10 3 11 12 13 14 2 1
4 5 6 7 8 9 10 11 3 12 13 14 2 1
4 5 6 7 8 9 10 11 12 3 13 14 2 1
4 5 6 7 8 9 10 11 12 13 3 14 2 1
4 5 6 7 8 9 10 11 12 13 14 3 2 1
4 5 6 7 8 9 10 11 12 13 14 1
5 4 6 7 8 9 10 11 12 13 14 3 2 1
5 6 4 7 8 9 10 11 12 13 14 3 2 1
5 6 7 4 8 9 10 11 12 13 14 3 2 1
5 6 7 8 4 9 10 11 12 13 14 3 2 1
5 6 7 8 9 4 10 11 12 13 14 3 2 1
5 6 7 8 9 10 4 11 12 13 14 3 2 1
5 6 7 8 9 10 11 4 12 13 14 3 2 1
5 6 7 8 9 10 11 12 4 13 14 3 2 1
5 6 7 8 9 10 11 12 13 4 14 3 2 1
5 6 7 8 9 10 11 12 13 14 4 3 2 1
5 6 7 8 9 10 11 12 13 14 2 1
6 5 7 8 9 10 11 12 13 14 4 3 2 1
6 7 5 8 9 10 11 12 13 14 4 3 2 1
6 7 8 5 9 10 11 12 13 14 4 3 2 1
6 7 8 9 5 10 11 12 13 14 4 3 2 1
6 7 8 9 10 5 11 12 13 14 4 3 2 1
6 7 8 9 10 11 5 12 13 14 4 3 2 1
6 7 8 9 10 11 12 5 13 14 4 3 2 1
6 7 8 9 10 11 12 13 5 14 4 3 2 1
6 7 8 9 10 11 12 13 14 5 4 3 2 1
6 7 8 9 10 11 12 13 14 3 2 1
7 6 8 9 10 11 12 13 14 5 4 3 2 1
7 8 6 9 10 11 12 13 14 5 4 3 2 1
7 8 9 6 10 11 12 13 14 5 4 3 2 1
7 8 9 10 6 11 12 13 14 5 4 3 2 1
7 8 9 10 11 6 12 13 14 5 4 3 2 1
7 8 9 10 11 12 6 13 14 5 4 3 2 1
7 8 9 10 11 12 13 6 14 5 4 3 2 1
7 8 9 10 11 12 13 14 6 5 4 3 2 1
7 8 9 10 11 12 13 14 4 3 2 1
8 7 9 10 11 12 13 14 6 5 4 3 2 1
8 9 7 10 11 12 13 14 6 5 4 3 2 1
8 9 10 7 11 12 13 14 6 5 4 3 2 1
8 9 10 11 7 12 13 14 6 5 4 3 2 1
8 9 10 11 12 7 13 14 6 5 4 3 2 1
8 9 10 11 12 13 7 14 6 5 4 3 2 1
8 9 10 11 12 13 14 7 6 5 4 3 2 1
8 9 10 11 12 13 14 5 4 3 2 1
9 8 10 11 12 13 14 7 6 5 4 3 2 1
9 10 8 11 12 13 14 7 6 5 4 3 2 1
9 10 11 8 12 13 14 7 6 5 4 3 2 1
9 10 11 12 8 13 14 7 6 5 4 3 2 1
9 10 11 12 13 8 14 7 6 5 4 3 2 1
9 10 11 12 13 14 8 7 6 5 4 3 2 1
9 10 11 12 13 14 6 5 4 3 2 1
10 9 11 12 13 14 8 7 6 5 4 3 2 1
10 11 9 12 13 14 8 7 6 5 4 3 2 1
10 11 12 9 13 14 8 7 6 5 4 3 2 1
10 11 12 13 9 14 8 7 6 5 4 3 2 1
10 11 12 13 14 9 8 7 6 5 4 3 2 1
10 11 12 13 14 7 6 5 4 3 2 1
11 10 12 13 14 9 8 7 6 5 4 3 2 1
11 12 10 13 14 9 8 7 6 5 4 3 2 1
11 12 13 10 14 9 8 7 6 5 4 3 2 1
11 12 13 14 10 9 8 7 6 5 4 3 2 1
11 12 13 14 8 7 6 5 4 3 2 1
12 11 13 14 10 9 8 7 6 5 4 3 2 1
12 13 11 14 10 9 8 7 6 5 4 3 2 1
12 13 14 11 10 9 8 7 6 5 4 3 2 1
12 13 14 9 8 7 6 5 4 3 2 1
13 12 14 11 10 9 8 7 6 5 4 3 2 1
13 14 12 11 10 9 8 7 6 5 4 3 2 1
13 14 10 9 8 7 6 5 4 3 2 1
14 13 12 11 10 9 8 7 6 5 4 3 2 1

Заключение

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

На самом деле, вместо самостоятельного написания алгоритмов сортировки программисты на Python используют стандартные функции и методы языка, такие как и . Эти функции отлажены и работают быстро и эффективно.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector