Loading [MathJax]/jax/output/HTML-CSS/jax.js

Сортировка вставками

Сортировка вставками, имея по-прежнему O(n2), работает несколько иначе. Она всегда поддерживает в сортированном виде подсписок на нижних индексах списка. Каждый новый элемент “вставляется” в упорядоченный на прошлой итерации подсписок так, чтобы тот остался сортированным и стал на один элемент больше. Рисунок 4 демонстрирует процесс сортировки вставками. Затенённые элементы представляют собой упорядоченные подсписки, которые алгоритм создаёт на каждом проходе.

../_images/insertionsort.png

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

На рисунке 5 детально показан пятый проход. В этой точке алгоритма сортированный список из пяти элементов содержит 17, 26, 54, 77 и 93. Мы хотим вставить в него 31. Первое сравнение с 93 приводит к тому, что 93 сдвигается вправо. Так же сдвигаются 77 и 54. Когда мы наталкиваемся на элемент 26, процесс смещения прекращается, и 31 становится на свободное место. Теперь у нас есть отсортироанный список из шести элементов.

../_images/insertionpass.png

Реализация insertionSort (ActiveCode 4) демонстрирует, что вновь выполняется n1 проход для сортировки n элементов. Итерации начинаются с индекса 1 и движутся до n1 позиции, поскольку все эти элементы должны быть вставлены в отсортированный список. В строке 8 происходит операция сдвига, которая перемещает значение на одну позицию вверх по списку, создавая место для вставки. Помните, что полноценный обмен, как в предыдущих алгоритмах, здесь не происходит.

Максимальное количество сравнений для сортировки вставками равно сумме первых n1 целых. Вновь, это O(n2). Однако, в наилучшем случае на каждом проходе потребуется всего одно сравнение. Это произойдёт, когда список уже отсортирован.

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


 
1
def insertionSort(alist):
2
   for index in range(1,len(alist)):
3
4
     currentvalue = alist[index]
5
     position = index
6
7
     while position>0 and alist[position-1]>currentvalue:
8
         alist[position]=alist[position-1]
9
         position = position-1
10
11
     alist[position]=currentvalue
12
13
alist = [54,26,93,17,77,31,44,55,20]
14
insertionSort(alist)
15
print(alist)
16


Сортировка вставками (lst_insertion)



Для большей детализации, CodeLens 4 позволят вам пошагово пройти весь алгоритм.

1def insertionSort(alist):
2   for index in range(1,len(alist)):
3
4     currentvalue = alist[index]
5     position = index
6
7     while position>0 and alist[position-1]>currentvalue:
8         alist[position]=alist[position-1]
9         position = position-1
10
11     alist[position]=currentvalue
12
13alist = [54,26,93,17,77,31,44,55,20]
14insertionSort(alist)
15print(alist)
Step 1 of 107
line that has just executed

next line to execute

Code visualized with Online Python Tutor
Frames
Objects

Трассировка сортировки вставками (insertionsortcodetrace)

Q-22: Предположим, у вас есть следующий список чисел для сортировки: [15, 5, 4, 18, 12, 19, 14, 10, 8, 20] Какой из вариантов ниже соответствует частично отсортированному списку после третьего прохода сортировки вставками?





Next Section - Сортировка Шелла