Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекции / Лекция_6_Элементарные_алгоритмы_сортировки_ipynb_Colab

.pdf
Скачиваний:
0
Добавлен:
28.06.2026
Размер:
1.33 Mб
Скачать

Элементарные алгоритмы сортировки

Сортировка

Сортировка упорядочение элементов последовательности в возрастающем порядке.

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

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

Требования к ключам элементов

Для множества ключей должно быть определенно отношение порядка «<».

Причем для любых 3-х ключей (например a, b, c) должны выполняться такие условия:

Закон трихотомии. Справедливым является одно и только одно из соотношений:

,

,

.

и

, то

.

Закон

транзитивности. Если

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

Закон трихотомии

В качестве ключей сортировки будем как и прежде использовать возраст кошки.

Закон транзитивности

Виды сортировки

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

Математическая формулировка:

Для любых индексов в последовательности

, в случае если ключи одинаковы, то и

.

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

Устойчивая сортировка

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

правее Кузи. В сортированной последовательности эти элементы сменили свое местоположение, но друг относительно друга они сохранили порядок следования. Т.е. Тимка стоит правее Кузи.

Алгоритмы сортировки которые сохраняют порядок при сортировке называют устойчивыми.

Алгоритмы устойчивой и неустойчивой сортировки

Алгоритмы устойчивой сортировки

Алгоритмы неустойчивой сортировки

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

Сортировка выбором

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

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

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

Сортировка Шелла

Гномья сортировка

Пирамидальная сортировка

Сортировка с помощью двоичного дерева

Плавная сортировка

Сортировка Timsort

Быстрая сортировка

В таблице приведены примеры алгоритмов как устойчивой так и неустойчивой сортировки.

Внешняя и внутренняя сортировки

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

Доступ возможен к произвольному элементу последовательности.

Элементы последовательности упорядочиваются в памяти без дополнительных затрат.

Внешняя сортировка данные не помещаются в оперативную память.

Последовательный доступ к элементу последовательности. Т.е. можно прочесть только текущий элемент, за ним следующий и т. д.

Затраты на свободную навигацию по элементам неоправданно высоки.

Некоторые критерии алгоритмов сортировки

Естественность поведения эффективность метода при обработке уже упорядоченных или частично упорядоченных данных. Алгоритм ведёт себя естественно, если учитывает эту характеристику входной последовательности и работает лучше.

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

1 блок. Квадратичные сортировки (основа)

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

Сведение о алгоритме

Алгоритм сортировки выбором.

Сложность по времени в наихудшем случае

Затраты памяти

Принцип работы алгоритма

1.Последовательность разбивается на две части. Отсортированную и не отсортированную. В качестве отсортированной части обычно выбирается правая часть последовательности.

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

3.Алгоритм прекращает свою работу в случае отсутствия обменов при проходе по не отсортированной части

последовательности.

Графическая иллюстрация работы алгоритма

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

вертикальной стрелкой).

b) При следующем проходе. Действия повторяются. Только теперь размер не отсортированной части последовательности меньше. При этом проходе было выполнено два обмена. После этого последний элемент не отсортированной части становится первым элементом отсортированной части.

c) Выполняется попарный проход по не отсортированной части последовательности. За весь проход не было выполнено ни одного обмена. Алгоритм завершается. Как можно видеть последовательность отсортирована.

Реализация алгоритма на Python

1.2 Сортировка выбором

Сведение о алгоритме

Алгоритм сортировки выбором.

Сложность по времени в наихудшем случае

Затраты памяти

Принцип работы алгоритма

1.Выполняется проход по сортируемой последовательности.

2.Первый элемент не отсортированной подпоследовательности принимается за минимальный и сохраняется его индекс.

3.Выполняется проход по не отсортированной части последовательности в поиске минимального элемента.

4.Происходит обмен найденного минимального члена и первого члена не отсортированной подпоследовательности.

Графическая иллюстрация работы алгоритма

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

2)На втором шаге опять производиться поиск минимума в не отсортированной подпоследовательности (в примере она подчеркнута). В этом примере минимальный элемент совпадает с первым элементом. Поэтому обмен не производится.

3)И опять производиться поиск минимума в не отсортированной подпоследовательности (в примере она подчеркнута). В этом примере минимальный элемент равен 3. Производим обмен с первым элементом не отсортированной подпоследовательности.

4)И опять производиться поиск минимума в не отсортированной подпоследовательности (в примере она подчеркнута). В этом примере минимальный элемент равен 5. Производим обмен с первым элементом не отсортированной подпоследовательности.

Длинна не отсортированной подпоследовательности равна 0. Следовательно алгоритм считается законченным. И действительно данные массива расположены в возрастающей последовательности.

Как выполнить обмен двух элементов последовательности

Реализация алгоритма на Python

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

Сведение о алгоритме

Алгоритм сортировки вставками.

Сложность по времени в наихудшем случае

Затраты памяти

Принцип работы алгоритма

1.Последовательность разбивается на две части. Отсортированную и не отсортированную. В качестве отсортированной части обычно выбирается левая часть последовательности.

2.Выбирается первый элемент не отсортированной последовательности и для него находится позиция в отсортированной

части последовательности. Правило нахождения позиции для элемента со значением :

3.Значение устанавливается на найденную позицию со сдвигом элементов стоящих справа от найденной позиции.

4.Алгоритм продолжается до исчерпания не отсортированной части последовательности.

Графическая иллюстрация работы алгоритма

a)Вначале вся последовательность является не отсортированной. Поэтому первый ее элемент сразу становится первым членом отсортированной части. Довольно часто этот шаг просто опускают начиная со второго члена последовательности.

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

c)Выбираем первый член не отсортированной последовательности (черная стрелка) и находим для него позицию (оранжевая стрелка). Ставим элемент на эту позицию. Сдвигаем часть отсортированной позиции (выделена оранжевым прямоугольником)

на один шаг вправо.

d) Выбираем первый член не отсортированной последовательности (черная стрелка) и находим для него позицию (оранжевая

стрелка). Так как позиция совпадает с положением элемента то ничего не делаем.

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

Реализация алгоритма на Python

2 блок. Вариации и улучшения пузырька (обзорно)

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

Сведение о алгоритме

Сложность по времени в наихудшем случае

Описание сути алгоритма

Сортировка перемешиванием является модификацией алгоритма сортировки пузырьком.

Сутью этой модификации является следующие наблюдения.

Первая перестановка в последовательности начинается с определенного индекса и при следующем проходе можно начинать с этого индекса, а не с начала последовательности.

При проходе в одну сторону элемент сдвигается на одну позицию к соответствующему краю последовательности. И если

чередовать проходы с начала последовательности до ее конца с проходами в обратном направлении то можно обеспечить более быстрое «всплывание» элемента к нужному краю последовательности.

Именно реализация этих изменений при работе алгоритма сортировки пузырьком и получила название сортировки перемешиванием.

Описание алгоритма

1.Объявляем две дополнительные переменные для хранения границ с которых нужно начинать проход по элементам последовательности (left и right соответственно) и переменную для контроля наличия факта обмена (control). Устанавливаем значение left = 0, right — индексу последнего элемента последовательности, control = right. Перейти к пункту 2.

2.Начиная от left и до right выполняем проход по элементам последовательности. Если текущий элемент больше следующего элемента то провести их обмен и установить значение control равной индексу текущего элемента. После прохода установить значение right равный control. Перейти к пункту 3.

3.Начиная от right до left выполняем обратный проход по элементам последовательности. Если текущий элемент меньше предыдущего то выполняем их обмен и устанавливаем значение control равным индексу текущего элемента. После

прохода устанавливаем значение left равным control. Перейти в пункту 4.

4.Если left < right вернуться к пункту 2. В противном случае закончить алгоритм.

1.В качестве начальных значений устанавливаем left = 0, right = control = 4. Начинаем проход в прямом направлении от left до right. Если текущий элемент больше следующего то совершаем их обмен и устанавливаем control равный индексу текущего элемента. После того как закончили проход устанавливаем значение right равный control.

2.Выполняем обратный проход начиная от right до left. Если текущий элемент меньше предыдущего (отчет ведем от начала последовательности) то производим их обмен и устанавливаем значение control равный индексу текущего элемента. После прохода устанавливаем значение left равным control.

3.Выполняем прямой проход от left до right. Обменов не было следовательно rignt = control = left. Выполняем обратный проход (но так как right = left он нулевой длинны). Проводим проверку left < right. Это не так. Заканчиваем алгоритм.

Реализация алгоритма на Python

def cocktail_sort(sequence):

 

 

 

 

 

left=

0

 

 

 

#Леваяграницанеотсортированнойчасти

right=

len(sequence) - 1

 

#Праваяграницанеотсортированнойчасти

control=right

 

 

 

#Переменнаядлязапоминанияпоследнегообмена

while left<right:

 

#Покаграницынесомкнулись

 

 

#Прямойпроход(слеванаправо)

 

 

 

 

 

 

for i

in range(left,right

):

 

 

 

 

 

if sequence [i] >sequence

[i+

1]:

 

 

 

 

 

#Обменсоседнихэлементовеслиони,стоятв

 

 

неправильномпорядке

 

sequence

[i],sequence [i+

1] =sequence

[i+

1],sequence [i]

 

control=i

 

 

#Запоминаеминдекспоследнегообмена

 

right=control

 

 

#Сдвигаемправуюграницу

 

 

 

#Обратныйпроход(справаналево)

 

 

 

 

 

 

for i

in range(right,left,

 

-1):

 

 

 

 

if sequence [i] <sequence

[i-

1]:

 

 

 

 

 

#Обменсоседнихэлементовеслиони,стоятв

 

 

неправильномпорядке

 

sequence

[i],sequence [i-

1] =sequence

[i-

1],sequence [i]

 

control=i

 

 

#Запоминаеминдекспоследнегообмена

 

left=control

 

 

#Сдвигаемлевуюграницу

 

 

 

 

 

 

 

 

 

 

 

2.2 Гномья сортировка.

При чем тут гномы???

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

Сведение о алгоритме

Алгоритм гномьей сортировки.

Сложность по времени в наихудшем случае

Затраты памяти

Принцип работы алгоритма

1.В качестве опорного берем первый элемент последовательности. Вводим дополнительную переменную, для хранения индекса. Устанавливаем ее равной индексу первого элемента.

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

3.Если опорный элемент больше следующего, то устанавливаем значение переменной для хранения индекса равным значению индекса следующего элемента. Производим обмен опорного и следующего элемента. В качестве опорного выбираем предыдущий. Повторяем до тех пор пока или не дойдем до начала последовательности или опорный элемент не станет меньше следующего. После чего в качестве опорного выбираем элемент индекс которого хранится во вспомогательной переменной. И повторяем пункт 2.

Графическая иллюстрация работы алгоритма

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

2.На втором шаге опорный элемент больше следующего, поэтому устанавливаем значение переменной для хранения индекса равной индексу следующего элемента. И выполняем обмен.

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

4.В качестве опорного выбирается элемент с сохраненным индексом. Опорный меньше следующего. В качестве опорного выбираем следующий элемент.

5.На шаге 5, опорный больше следующего, поэтому устанавливаем значение переменной для хранения индекса равной индексу следующего элемента. И выполняем обмен.

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

7.Опорный элемент выступает в качестве последнего элемента в последовательности. Алгоритм окончен.

Реализация алгоритма на Python

def gnome_sort(sequence):

 

index=

1

 

#Переменнаядлявозвратапослесерииобменов

i=

0

 

#Текущийиндекс

n=

len(sequence)

#Длинапоследовательности

while i<n-

1:

#Поканедошлипоследнегоэлемента