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

Данный метод сортировки был предложен Дж. У. Дж. Уильямсом и Р.У. Флойдом в 1964 году. Пирамидальная сортировка в некотором роде является модификацией такого подхода, как сортировка выбором, с тем лишь отличием, что минимальный (или максимальный) элемент из неотсортированной последовательности выбирается за меньшее количество операций. Для такого быстрого выбора из этой неотсортированной последовательности строится некоторая структура. Именно суть данного метода и состоит в построении такой структуры, которая называется пирамидой.

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

Просеивание – это построение новой пирамиды по следующему алгоритму: новый элемент помещается в вершину дерева, далее он перемещается («просеивается») по пути вниз на основе сравнения с дочерними элементами. Спуск завершается, если результат сравнения с дочерними элементами соответствует ключу сортировки.

Последовательность чисел формирует пирамиду, если для всех выполняются неравенства (или ). Элементы и называются потомками элемента .

Массив чисел 12 10 7 5 8 7 3 является пирамидой. Такой массив удобно изображать в виде дерева. Первый элемент массива, элементы которого образуют собой пирамиду, является наибольшим (или наименьшим). Если массив представлен в виде пирамиды, то массив легко отсортировать.

Алгоритм пирамидальной сортировки.

Шаг 1. Преобразовать массив в пирамиду (рис. 1. А).

Шаг 2. Использовать алгоритм сортировки пирамиды (рис. 1. В – H).

Алгоритм преобразования массива в пирамиду (построение пирамиды). Пусть дан массив .

Шаг 1. Устанавливаем .

Шаг 2. Перебираем элементы массива в цикле справа налево для . Если неравенства не выполняются, то повторяем перестановки с наибольшим из потомков. Перестановки завершаются при выполнении неравенств .

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

Рассмотрим массив размерности n, который представляет пирамиду .

Шаг 1. Переставляем элементы и .

Шаг 2. Определяем . Это эквивалентно тому, что в массиве из дальнейшего рассмотрения исключается элемент .

Шаг 3. Рассматриваем массив , который получается из исходного за счет исключения последнего элемента. Данный массив из-за перестановки элементов уже не является пирамидой. Но такой массив легко преобразовать в пирамиду. Это достигается повторением перестановки значения элемента из с наибольшим из потомков. Такая перестановка продолжается до тех пор, пока элемент из не окажется на месте элемента и при этом будут выполняться неравенства , . Тем самым определяется новое место для значения первого элемента из (рис. 1. С).

Шаг 4. Повторяем шаги 2, 3, 4 до тех пор, пока не получим . Произвольный массив можно преобразовать в пирамиду (рис. 1. D – H).

 

    A       B  
    C       D  
    E       F  
    G       H  

 

Рис.1. Демонстрация бинарной пирамидальной сортировки по неубыванию

 

 

Построение пирамиды, ее сортировка и «просеивание» элементов реализуются с помощью рекурсии. Базой рекурсии при этом выступает пирамида из одного элемента, а сортировка и просеивание n элементов сводятся посредством декомпозиции к аналогичным действиям с пирамидой из элемента.

 

//Описание функции бинарной пирамидальной сортировки

void Binary_Pyramidal_Sort (int k,int *x){

Build_Pyramid(k/2+1,k-1,x);

Sort_Piramid(k-1,x);

}

 

//Построение пирамиды

void Build_Pyramid (int k, int r, int *x){

Sifting(k,r,x);

if (k > 0)

Build_Pyramid(k-1,r,x);

}

 

//Сортировка пирамиды

void Sort_Piramid (int k, int *x){

Exchange (0,k,x);

Sifting(0,k-1,x);

if (k > 1)

Sort_Piramid(k-1,x);

}

 

//"Просеивание" элементов

void Sifting (int left, int right, int *x){

int q, p, h;

q=2*left+1;

p=q+1;

if (q <= right){

if (p <= right && x[p] > x[q])

q = p;

if (x[left] < x[q]){

Exchange (left, q, x);

Sifting(q, right, x);

}

}

}

//процедура обмена двух элементов

void Exchange (int i, int j, int *x){

int tmp;

tmp = x[i];

x[i] = x[j];

x[j] = tmp;

}

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

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

Тогда общее время сортировки (с учетом построения пирамиды) будет равно: .

Пирамидальная сортировка не использует дополнительной памяти. Метод не является устойчивым: по ходу работы массив так «перетряхивается», что исходный порядок элементов может измениться случайным образом. Поведение неестественно: частичная упорядоченность массива никак не учитывается. Данная сортировка на почти отсортированных массивах работает также долго, выигрыш ее получается только на больших n.