Сортировка Шелла
Сортировку Шелла придумал Дональд
Л. Шелл. Ее необычность состоит в том, что она рассматривает весь
список как совокупность перемешанных подсписков. На первом шаге эти
подсписки представляют собой просто пары элементов. На втором шаге
в каждой группе по четыре элемента. При повторении процесса число
элементов в каждом подсписке увеличивается, а число подсписков, соответственно,
падает. На рисунке ниже изображены подсписки, которыми можно воспользоваться
при сортировке списка из 16 элементов.
На рисунке (а) изображены восемь подсписков,
по два элемента в каждом, в которых первый подсписок содержит первый
и девятый элементы, второй подсписок - второй и десятый элементы,
и так далее. На рисунке (б) мы видим уже четыре подсписка по четыре
элемента в каждом. Первый подсписок на этот раз содержит первый, пятый,
девятый и тринадцатый элементы. Второй подсписок состоит из второго,
шестого, десятого и четырнадцатого элементов. На рисунке (в) показаны
два подсписка, состоящие из элементов с нечетными и четными номерами
соответственно. На рисунке (г) мы вновь возвращаемся к одному списку.
Сортировка подсписков выполняется путем однократного
применения сортировки вставками. В результате
мы получаем следующий алгоритм:
ShellSort(list, N)
list сортируемый список элементов
N число элементов в списке
passes = [log_2 N]
while (passes >= 1) do
increment = 2^passes-1
for start = 1 to increment do
InsertionSort(list, N, start, increment)
end for
passes = passes - 1
end while
Переменная increment содержит
величину шага между номерами элементов подсписка. (На рисунке шаг
принимает значения 8, 4, 2 и 1.) В алгоритме мы начинаем с шага, на
1 меньшего наибольшей степени двойки, меньшей, чем длина списка. Поэтому
для списка из 1000 элементов первое значения шага равно 511. Значение
шага также равно числу подсписков. Элементы первого подсписка имеют
номера 1 и 1 + increment; первым элементов последнего подсписка служит
элемент с номером increment.
При последнем исполнении цикла while значение
переменной passes будет равно 1, поэтому при последнем вызове функции
InsertionSort значение переменной будет равно 1.
|
|