Мотивация и краткое содержание

Цель занятия

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

Основные объекты

  • Сортировка пузырьком
  • Сортировка выбором
  • Сортировка вставкой
  • Сортировка Шелла

В начало

Bubble sort

Основная информация

  • Сортировка пузырьком.
  • Простой алгоритм, но неэффективный. Его даже называют настолько плохим, что он не нужен в качестве примера алгоритма при обучении. Именно поэтому мы его разберем!

Псевдокод

1  BubbleSort(Array):
2      n = length(Array)
3      repeat
4          swapped = False
5          for i = 1 to> n-1 do
6              if Array[i-1] > Array[i] then
7                  swap(Array[i-1], Array[i])
8                  swapped = True
9          n = n - 1
10     until not swapped

Зато красивая визуализация.

Пример работы

In [1]:
from bubblesort import BubbleArray, bubble_sort, bubble_sort_improved
demo_array = BubbleArray([4, 5, 8, 3, 1, 2, 6, 7, 9])
In [2]:
bubble_sort(demo_array)
(4 5 8 3 1 2 6 7 9) -> (4 5 3 8 1 2 6 7 9)
(4 5 3 8 1 2 6 7 9) -> (4 5 3 1 8 2 6 7 9)
(4 5 3 1 8 2 6 7 9) -> (4 5 3 1 2 8 6 7 9)
(4 5 3 1 2 8 6 7 9) -> (4 5 3 1 2 6 8 7 9)
(4 5 3 1 2 6 8 7 9) -> (4 5 3 1 2 6 7 8 9)
(4 5 3 1 2 6 7 8 9) -> (4 3 5 1 2 6 7 8 9)
(4 3 5 1 2 6 7 8 9) -> (4 3 1 5 2 6 7 8 9)
(4 3 1 5 2 6 7 8 9) -> (4 3 1 2 5 6 7 8 9)
(4 3 1 2 5 6 7 8 9) -> (3 4 1 2 5 6 7 8 9)
(3 4 1 2 5 6 7 8 9) -> (3 1 4 2 5 6 7 8 9)
(3 1 4 2 5 6 7 8 9) -> (3 1 2 4 5 6 7 8 9)
(3 1 2 4 5 6 7 8 9) -> (1 3 2 4 5 6 7 8 9)
(1 3 2 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
In [3]:
# from bubblesort import *
demo_array = BubbleArray([4, 5, 8, 3, 1, 2, 6, 7, 9])
bubble_sort(demo_array, show_wasted=False)
(4 5 8 3 1 2 6 7 9) -> (4 5 3 8 1 2 6 7 9)
(4 5 3 8 1 2 6 7 9) -> (4 5 3 1 8 2 6 7 9)
(4 5 3 1 8 2 6 7 9) -> (4 5 3 1 2 8 6 7 9)
(4 5 3 1 2 8 6 7 9) -> (4 5 3 1 2 6 8 7 9)
(4 5 3 1 2 6 8 7 9) -> (4 5 3 1 2 6 7 8 9)
(4 5 3 1 2 6 7 8 9) -> (4 3 5 1 2 6 7 8 9)
(4 3 5 1 2 6 7 8 9) -> (4 3 1 5 2 6 7 8 9)
(4 3 1 5 2 6 7 8 9) -> (4 3 1 2 5 6 7 8 9)
(4 3 1 2 5 6 7 8 9) -> (3 4 1 2 5 6 7 8 9)
(3 4 1 2 5 6 7 8 9) -> (3 1 4 2 5 6 7 8 9)
(3 1 4 2 5 6 7 8 9) -> (3 1 2 4 5 6 7 8 9)
(3 1 2 4 5 6 7 8 9) -> (1 3 2 4 5 6 7 8 9)
(1 3 2 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
In [4]:
# from bubblesort import *
demo_array = BubbleArray([4, 5, 8, 3, 1, 2, 6, 7, 9])
bubble_sort(demo_array, show_wasted=True)
(4 5 8 3 1 2 6 7 9) -> (4 5 8 3 1 2 6 7 9)
(4 5 8 3 1 2 6 7 9) -> (4 5 8 3 1 2 6 7 9)
(4 5 8 3 1 2 6 7 9) -> (4 5 3 8 1 2 6 7 9)
(4 5 3 8 1 2 6 7 9) -> (4 5 3 1 8 2 6 7 9)
(4 5 3 1 8 2 6 7 9) -> (4 5 3 1 2 8 6 7 9)
(4 5 3 1 2 8 6 7 9) -> (4 5 3 1 2 6 8 7 9)
(4 5 3 1 2 6 8 7 9) -> (4 5 3 1 2 6 7 8 9)
(4 5 3 1 2 6 7 8 9) -> (4 5 3 1 2 6 7 8 9)
(4 5 3 1 2 6 7 8 9) -> (4 5 3 1 2 6 7 8 9)
(4 5 3 1 2 6 7 8 9) -> (4 3 5 1 2 6 7 8 9)
(4 3 5 1 2 6 7 8 9) -> (4 3 1 5 2 6 7 8 9)
(4 3 1 5 2 6 7 8 9) -> (4 3 1 2 5 6 7 8 9)
(4 3 1 2 5 6 7 8 9) -> (4 3 1 2 5 6 7 8 9)
(4 3 1 2 5 6 7 8 9) -> (4 3 1 2 5 6 7 8 9)
(4 3 1 2 5 6 7 8 9) -> (4 3 1 2 5 6 7 8 9)
(4 3 1 2 5 6 7 8 9) -> (3 4 1 2 5 6 7 8 9)
(3 4 1 2 5 6 7 8 9) -> (3 1 4 2 5 6 7 8 9)
(3 1 4 2 5 6 7 8 9) -> (3 1 2 4 5 6 7 8 9)
(3 1 2 4 5 6 7 8 9) -> (3 1 2 4 5 6 7 8 9)
(3 1 2 4 5 6 7 8 9) -> (3 1 2 4 5 6 7 8 9)
(3 1 2 4 5 6 7 8 9) -> (3 1 2 4 5 6 7 8 9)
(3 1 2 4 5 6 7 8 9) -> (1 3 2 4 5 6 7 8 9)
(1 3 2 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
In [5]:
# from bubblesort import *
demo_array = BubbleArray(range(9, 0, -1))
bubble_sort(demo_array, show_wasted=True)
(9 8 7 6 5 4 3 2 1) -> (8 9 7 6 5 4 3 2 1)
(8 9 7 6 5 4 3 2 1) -> (8 7 9 6 5 4 3 2 1)
(8 7 9 6 5 4 3 2 1) -> (8 7 6 9 5 4 3 2 1)
(8 7 6 9 5 4 3 2 1) -> (8 7 6 5 9 4 3 2 1)
(8 7 6 5 9 4 3 2 1) -> (8 7 6 5 4 9 3 2 1)
(8 7 6 5 4 9 3 2 1) -> (8 7 6 5 4 3 9 2 1)
(8 7 6 5 4 3 9 2 1) -> (8 7 6 5 4 3 2 9 1)
(8 7 6 5 4 3 2 9 1) -> (8 7 6 5 4 3 2 1 9)
(8 7 6 5 4 3 2 1 9) -> (7 8 6 5 4 3 2 1 9)
(7 8 6 5 4 3 2 1 9) -> (7 6 8 5 4 3 2 1 9)
(7 6 8 5 4 3 2 1 9) -> (7 6 5 8 4 3 2 1 9)
(7 6 5 8 4 3 2 1 9) -> (7 6 5 4 8 3 2 1 9)
(7 6 5 4 8 3 2 1 9) -> (7 6 5 4 3 8 2 1 9)
(7 6 5 4 3 8 2 1 9) -> (7 6 5 4 3 2 8 1 9)
(7 6 5 4 3 2 8 1 9) -> (7 6 5 4 3 2 1 8 9)
(7 6 5 4 3 2 1 8 9) -> (6 7 5 4 3 2 1 8 9)
(6 7 5 4 3 2 1 8 9) -> (6 5 7 4 3 2 1 8 9)
(6 5 7 4 3 2 1 8 9) -> (6 5 4 7 3 2 1 8 9)
(6 5 4 7 3 2 1 8 9) -> (6 5 4 3 7 2 1 8 9)
(6 5 4 3 7 2 1 8 9) -> (6 5 4 3 2 7 1 8 9)
(6 5 4 3 2 7 1 8 9) -> (6 5 4 3 2 1 7 8 9)
(6 5 4 3 2 1 7 8 9) -> (5 6 4 3 2 1 7 8 9)
(5 6 4 3 2 1 7 8 9) -> (5 4 6 3 2 1 7 8 9)
(5 4 6 3 2 1 7 8 9) -> (5 4 3 6 2 1 7 8 9)
(5 4 3 6 2 1 7 8 9) -> (5 4 3 2 6 1 7 8 9)
(5 4 3 2 6 1 7 8 9) -> (5 4 3 2 1 6 7 8 9)
(5 4 3 2 1 6 7 8 9) -> (4 5 3 2 1 6 7 8 9)
(4 5 3 2 1 6 7 8 9) -> (4 3 5 2 1 6 7 8 9)
(4 3 5 2 1 6 7 8 9) -> (4 3 2 5 1 6 7 8 9)
(4 3 2 5 1 6 7 8 9) -> (4 3 2 1 5 6 7 8 9)
(4 3 2 1 5 6 7 8 9) -> (3 4 2 1 5 6 7 8 9)
(3 4 2 1 5 6 7 8 9) -> (3 2 4 1 5 6 7 8 9)
(3 2 4 1 5 6 7 8 9) -> (3 2 1 4 5 6 7 8 9)
(3 2 1 4 5 6 7 8 9) -> (2 3 1 4 5 6 7 8 9)
(2 3 1 4 5 6 7 8 9) -> (2 1 3 4 5 6 7 8 9)
(2 1 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
In [6]:
# from bubblesort import *
demo_array = BubbleArray([4, 5, 8, 3, 1, 2, 6, 7, 9])
bubble_sort_improved(demo_array, show_wasted=True)
(4 5 8 3 1 2 6 7 9) -> (4 5 8 3 1 2 6 7 9)
(4 5 8 3 1 2 6 7 9) -> (4 5 8 3 1 2 6 7 9)
(4 5 8 3 1 2 6 7 9) -> (4 5 3 8 1 2 6 7 9)
(4 5 3 8 1 2 6 7 9) -> (4 5 3 1 8 2 6 7 9)
(4 5 3 1 8 2 6 7 9) -> (4 5 3 1 2 8 6 7 9)
(4 5 3 1 2 8 6 7 9) -> (4 5 3 1 2 6 8 7 9)
(4 5 3 1 2 6 8 7 9) -> (4 5 3 1 2 6 7 8 9)
(4 5 3 1 2 6 7 8 9) -> (4 5 3 1 2 6 7 8 9)
(4 5 3 1 2 6 7 8 9) -> (4 5 3 1 2 6 7 8 9)
(4 5 3 1 2 6 7 8 9) -> (4 3 5 1 2 6 7 8 9)
(4 3 5 1 2 6 7 8 9) -> (4 3 1 5 2 6 7 8 9)
(4 3 1 5 2 6 7 8 9) -> (4 3 1 2 5 6 7 8 9)
(4 3 1 2 5 6 7 8 9) -> (4 3 1 2 5 6 7 8 9)
(4 3 1 2 5 6 7 8 9) -> (4 3 1 2 5 6 7 8 9)
(4 3 1 2 5 6 7 8 9) -> (3 4 1 2 5 6 7 8 9)
(3 4 1 2 5 6 7 8 9) -> (3 1 4 2 5 6 7 8 9)
(3 1 4 2 5 6 7 8 9) -> (3 1 2 4 5 6 7 8 9)
(3 1 2 4 5 6 7 8 9) -> (1 3 2 4 5 6 7 8 9)
(1 3 2 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
In [7]:
# from bubblesort import *
demo_array = BubbleArray(range(9, 0, -1))
bubble_sort_improved(demo_array, show_wasted=True)
(9 8 7 6 5 4 3 2 1) -> (8 9 7 6 5 4 3 2 1)
(8 9 7 6 5 4 3 2 1) -> (8 7 9 6 5 4 3 2 1)
(8 7 9 6 5 4 3 2 1) -> (8 7 6 9 5 4 3 2 1)
(8 7 6 9 5 4 3 2 1) -> (8 7 6 5 9 4 3 2 1)
(8 7 6 5 9 4 3 2 1) -> (8 7 6 5 4 9 3 2 1)
(8 7 6 5 4 9 3 2 1) -> (8 7 6 5 4 3 9 2 1)
(8 7 6 5 4 3 9 2 1) -> (8 7 6 5 4 3 2 9 1)
(8 7 6 5 4 3 2 9 1) -> (8 7 6 5 4 3 2 1 9)
(8 7 6 5 4 3 2 1 9) -> (7 8 6 5 4 3 2 1 9)
(7 8 6 5 4 3 2 1 9) -> (7 6 8 5 4 3 2 1 9)
(7 6 8 5 4 3 2 1 9) -> (7 6 5 8 4 3 2 1 9)
(7 6 5 8 4 3 2 1 9) -> (7 6 5 4 8 3 2 1 9)
(7 6 5 4 8 3 2 1 9) -> (7 6 5 4 3 8 2 1 9)
(7 6 5 4 3 8 2 1 9) -> (7 6 5 4 3 2 8 1 9)
(7 6 5 4 3 2 8 1 9) -> (7 6 5 4 3 2 1 8 9)
(7 6 5 4 3 2 1 8 9) -> (6 7 5 4 3 2 1 8 9)
(6 7 5 4 3 2 1 8 9) -> (6 5 7 4 3 2 1 8 9)
(6 5 7 4 3 2 1 8 9) -> (6 5 4 7 3 2 1 8 9)
(6 5 4 7 3 2 1 8 9) -> (6 5 4 3 7 2 1 8 9)
(6 5 4 3 7 2 1 8 9) -> (6 5 4 3 2 7 1 8 9)
(6 5 4 3 2 7 1 8 9) -> (6 5 4 3 2 1 7 8 9)
(6 5 4 3 2 1 7 8 9) -> (5 6 4 3 2 1 7 8 9)
(5 6 4 3 2 1 7 8 9) -> (5 4 6 3 2 1 7 8 9)
(5 4 6 3 2 1 7 8 9) -> (5 4 3 6 2 1 7 8 9)
(5 4 3 6 2 1 7 8 9) -> (5 4 3 2 6 1 7 8 9)
(5 4 3 2 6 1 7 8 9) -> (5 4 3 2 1 6 7 8 9)
(5 4 3 2 1 6 7 8 9) -> (4 5 3 2 1 6 7 8 9)
(4 5 3 2 1 6 7 8 9) -> (4 3 5 2 1 6 7 8 9)
(4 3 5 2 1 6 7 8 9) -> (4 3 2 5 1 6 7 8 9)
(4 3 2 5 1 6 7 8 9) -> (4 3 2 1 5 6 7 8 9)
(4 3 2 1 5 6 7 8 9) -> (3 4 2 1 5 6 7 8 9)
(3 4 2 1 5 6 7 8 9) -> (3 2 4 1 5 6 7 8 9)
(3 2 4 1 5 6 7 8 9) -> (3 2 1 4 5 6 7 8 9)
(3 2 1 4 5 6 7 8 9) -> (2 3 1 4 5 6 7 8 9)
(2 3 1 4 5 6 7 8 9) -> (2 1 3 4 5 6 7 8 9)
(2 1 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
In [8]:
# from bubblesort import *
demo_array = BubbleArray([1, 2, 3, 5, 4, 6, 7, 8, 9])
bubble_sort_improved(demo_array, show_wasted=True)
(1 2 3 5 4 6 7 8 9) -> (1 2 3 5 4 6 7 8 9)
(1 2 3 5 4 6 7 8 9) -> (1 2 3 5 4 6 7 8 9)
(1 2 3 5 4 6 7 8 9) -> (1 2 3 5 4 6 7 8 9)
(1 2 3 5 4 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
In [9]:
# from bubblesort import *
demo_array = BubbleArray([1, 2, 3, 5, 4, 6, 7, 8, 9])
bubble_sort(demo_array, show_wasted=True)
(1 2 3 5 4 6 7 8 9) -> (1 2 3 5 4 6 7 8 9)
(1 2 3 5 4 6 7 8 9) -> (1 2 3 5 4 6 7 8 9)
(1 2 3 5 4 6 7 8 9) -> (1 2 3 5 4 6 7 8 9)
(1 2 3 5 4 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)
(1 2 3 4 5 6 7 8 9) -> (1 2 3 4 5 6 7 8 9)

Selection sort

Сортировка выбором - простой принцип: находится наименьший элемент, меняется местами с первым неотсортированным.

Псевдокод

1  SelectionSort(Array):
2      for i in 0..n-1
3          min = i
4          for j in i+1..n-1
5              if Array[j] < Array[min]
6                  min = j
7          if i != min
8              swap(Array, i, min)
</font>

Анализ сложности

  1. Сколько всего сравнений выполняется в сортировке?
  2. Сколько шагов во внешнем цикле?
  3. Сколько шагов во вложенном цикле?

Количество сравнений


  • непрозрачно
    Nsteps=i=0n1j=i+1n11
  • чуть лучше
    Nsteps=i=0n1ni1
  • интуитивный вариант
    Nsteps=i=1n1i
  • без сумм
    1+2+...+(n1)=n(n1)2
    </font>

Как решать рекуррентности?

Вопрос подробно рассматривается в книге "Конкретная математика" Р. Грэхема и Д. Кнута.

Доказательство корректности

Как организовано доказательство

Если в алгоритме присутствует цикл (то есть почти всегда)

  1. Инвариант цикла
  2. Сохранение инварианта
  3. Завершение цикла

Наш случай

Если в алгоритме присутствует цикл (то есть почти всегда):

  1. Инвариант: начало списка до i-го элемента отсортировано. При инициалиизации (пустой список) верно
  2. Сохранение инварианта: после итерации цикла i+=1; начало списка отстортировано
  3. Завершение цикла: i = длине списка, весь список отсортиррован

Определение отсортированного списка

Важно дать формальное определение, потому что оно будет имспользоваться при проверке сохранения инварианта

Такая перестановка (элементов массива), что для всех i , где i - индекс элемента в списке, AiAi+1 </font>

Почему так?

  1. Пустой список отсортирован по соглашению
  2. На каждом следующем шаге выбираем из списка минимальный элемент
  3. Здесь надо бы доказать, что в списке есть минимальный элемент, и мы извлекаем его :)
  4. Находим минимальный элемент, вставляем в конец отсортированного списка. При этом список остается отсортированным!
  5. Завершение цикла: мы добираемся до конца списка. Весь список отсортирован

Картинка - инварианты

В начало

Примеры работы алгоритма

In [10]:
from selection_sort import selection_sort, SelectionArray
array = SelectionArray([9, 3, 4, 6, 5, 7, 8, 2, 0, 1])
selection_sort(array)
select
(9 3 4 6 5 7 8 2 0 1)
(9 3 4 6 5 7 8 2 0 1)
(9 3 4 6 5 7 8 2 0 1)
(9 3 4 6 5 7 8 2 0 1)
(9 3 4 6 5 7 8 2 0 1)
(9 3 4 6 5 7 8 2 0 1)
(9 3 4 6 5 7 8 2 0 1)
(9 3 4 6 5 7 8 2 0 1)
(9 3 4 6 5 7 8 2 0 1)
swap
(0 3 4 6 5 7 8 2 9 1)
select
(0 3 4 6 5 7 8 2 9 1)
(0 3 4 6 5 7 8 2 9 1)
(0 3 4 6 5 7 8 2 9 1)
(0 3 4 6 5 7 8 2 9 1)
(0 3 4 6 5 7 8 2 9 1)
(0 3 4 6 5 7 8 2 9 1)
(0 3 4 6 5 7 8 2 9 1)
(0 3 4 6 5 7 8 2 9 1)
swap
(0 1 4 6 5 7 8 2 9 3)
select
(0 1 4 6 5 7 8 2 9 3)
(0 1 4 6 5 7 8 2 9 3)
(0 1 4 6 5 7 8 2 9 3)
(0 1 4 6 5 7 8 2 9 3)
(0 1 4 6 5 7 8 2 9 3)
(0 1 4 6 5 7 8 2 9 3)
(0 1 4 6 5 7 8 2 9 3)
swap
(0 1 2 6 5 7 8 4 9 3)
select
(0 1 2 6 5 7 8 4 9 3)
(0 1 2 6 5 7 8 4 9 3)
(0 1 2 6 5 7 8 4 9 3)
(0 1 2 6 5 7 8 4 9 3)
(0 1 2 6 5 7 8 4 9 3)
(0 1 2 6 5 7 8 4 9 3)
swap
(0 1 2 3 5 7 8 4 9 6)
select
(0 1 2 3 5 7 8 4 9 6)
(0 1 2 3 5 7 8 4 9 6)
(0 1 2 3 5 7 8 4 9 6)
(0 1 2 3 5 7 8 4 9 6)
(0 1 2 3 5 7 8 4 9 6)
swap
(0 1 2 3 4 7 8 5 9 6)
select
(0 1 2 3 4 7 8 5 9 6)
(0 1 2 3 4 7 8 5 9 6)
(0 1 2 3 4 7 8 5 9 6)
(0 1 2 3 4 7 8 5 9 6)
swap
(0 1 2 3 4 5 8 7 9 6)
select
(0 1 2 3 4 5 8 7 9 6)
(0 1 2 3 4 5 8 7 9 6)
(0 1 2 3 4 5 8 7 9 6)
swap
(0 1 2 3 4 5 6 7 9 8)
select
(0 1 2 3 4 5 6 7 9 8)
(0 1 2 3 4 5 6 7 9 8)
select
(0 1 2 3 4 5 6 7 9 8)
swap
(0 1 2 3 4 5 6 7 8 9)
In [11]:
array = SelectionArray(list(range(10)))
selection_sort(array)
select
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
select
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
select
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
select
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
select
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
select
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
select
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
select
(0 1 2 3 4 5 6 7 8 9)
(0 1 2 3 4 5 6 7 8 9)
select
(0 1 2 3 4 5 6 7 8 9)

Insertion sort

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

Псевдокод

1  InsertionSort(Array):
2      for i in 0..n-1
3          x = Array[i]
4          j = i - 1
5          while j >= 0 and Array[j] > x
6              Array[j+1] = Array[j] // "сдвиг" вправо
7              j = j - 1
8          Array[j+1] = x  // Вставка x в отсортированную часть
9          i = i + 1

Отличие от Selection Sort

  1. Основное отличие - достаточно вего 1го сравнения, когда k+1 элемент > k-го элемента
  2. selection sort будет "пробегать" все оставшиеся элементы
  3. selection sort записывает в память O(n) раз, а insertion sort - O(n2)

Также Insertion Sort:

  1. Стабильный
  2. Online
  3. In-place
</font>

Пояснения в картинках

Online - сортировка

Применение

  1. Простой алгоритм, который работает быстро на небольших массивах
  2. Используется при сортировке небольших массивов в алгоритмах divide and conquer
  3. Отлично работает для частично отсортированных последоваьтельностей

В начало

Примеры работы insertion sort

In [12]:
from insertion_sort import insertion_sort, InsertionArray
array = InsertionArray([9, 3, 4, 6, 5, 7, 8, 2, 0, 1])
insertion_sort(array)

array
( 9 3 4 6 5 7 8 2 0 1)
( 3 9 4 6 5 7 8 2 0 1)
( 3 4 9 6 5 7 8 2 0 1)
( 3 4 6 9 5 7 8 2 0 1)
( 3 4 6 5 9 7 8 2 0 1)
( 3 4 5 6 9 7 8 2 0 1)
( 3 4 5 6 7 9 8 2 0 1)
( 3 4 5 6 7 8 9 2 0 1)
( 3 4 5 6 7 8 2 9 0 1)
( 3 4 5 6 7 2 8 9 0 1)
( 3 4 5 6 2 7 8 9 0 1)
( 3 4 5 2 6 7 8 9 0 1)
( 3 4 2 5 6 7 8 9 0 1)
( 3 2 4 5 6 7 8 9 0 1)
( 2 3 4 5 6 7 8 9 0 1)
( 2 3 4 5 6 7 8 0 9 1)
( 2 3 4 5 6 7 0 8 9 1)
( 2 3 4 5 6 0 7 8 9 1)
( 2 3 4 5 0 6 7 8 9 1)
( 2 3 4 0 5 6 7 8 9 1)
( 2 3 0 4 5 6 7 8 9 1)
( 2 0 3 4 5 6 7 8 9 1)
( 0 2 3 4 5 6 7 8 9 1)
( 0 2 3 4 5 6 7 8 1 9)
( 0 2 3 4 5 6 7 1 8 9)
( 0 2 3 4 5 6 1 7 8 9)
( 0 2 3 4 5 1 6 7 8 9)
( 0 2 3 4 1 5 6 7 8 9)
( 0 2 3 1 4 5 6 7 8 9)
( 0 2 1 3 4 5 6 7 8 9)
Out[12]:
( 0 1 2 3 4 5 6 7 8 9)
In [13]:
from insertion_sort import insertion_sort, InsertionArray
array = InsertionArray([0, 1, 2, 8, 3, 4, 5, 6, 7, 9])
insertion_sort(array)

array
( 0 1 2 8 3 4 5 6 7 9)
( 0 1 2 3 8 4 5 6 7 9)
( 0 1 2 3 4 8 5 6 7 9)
( 0 1 2 3 4 5 8 6 7 9)
( 0 1 2 3 4 5 6 8 7 9)
Out[13]:
( 0 1 2 3 4 5 6 7 8 9)
In [14]:
from insertion_sort import insertion_sort, InsertionArray
array = InsertionArray([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
insertion_sort(array)

array
Out[14]:
( 0 1 2 3 4 5 6 7 8 9)

Shellsort

Сортировка Шелла (1959г.) - "улучшение" сортировки вставками / сортировки пузырьком

Идея сортировки

  1. Разобьем список на части (каждый k-й элемент)
  2. Отсортируем эти части insertion sort
  3. Повторим с другим разбиением c меньшим k, если k>1

Визуализация

Вопросы


- Почему Shell sort работает быстро?<br>
- И насколько быстро?<br>
- Какие свойства у этой сортировки?

</font>

Домашнее задание

  1. Реализуйте сортировку Шелла
  2. Оцените скорость работы для случайных и частично упорядоченных данны
  3. Попробуйте разные наборы шагов, подберите лучшие для различных типов входных данных

В начало

Ссылки

  1. [Как звучат алгоритмы сортировки](https://bit.ly/2U3A0Ey)
  2. [И еще](https://bit.ly/1g8XrEF)
В начало

Обратная связь

Не забудьте заполнить опрос по ссылке.

В начало