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

Все методы сортировок основаны на многократных просмотрах массивов v и выполнении определенных операций над их элементами. Как можно улучшить какой-либо из конкретных алгоритмов? По-видимому, путь таков: за каждый просмотр всего v или его части получать как можно больше информации. Одна из возможностей на этом пути открывается при представлении сортируемого массива в виде нелинейной структуры типа двоичного (бинарного) дерева D. На рис.1 показан такой граф D для v из n элементов, где 8 £ n < 16.

 

Рис. 1. Бинарное дерево последовательности (7)

В кружках-вершинах графа размещены элементы массива:

9, 14, 8, 1, 5, 4, 9, 12, 3, 17, 1, 3.                                               (7)

Целыми последовательными числами, начиная от 0 и далее, сверху вниз по уровням и слева направо на одном уровне пронумерованы все узлы, или вершины, D. Эти номера (адреса, индексы) проставлены около узлов. Именно такая адресация и будет использоваться в дальнейшем. У любого бинарного дерева имеется, и притом только один, корневой узел (корень), для которого нет предшественников (родителей). Любой другой узел имеет только одного предшественника и одного или двух преемников (прямых потомков). Высотой бинарного дерева называют число, равное количеству уровней расположения его узлов без единицы.

Ниже используются следующие стандартные для информатики обозначения: éxù - “потолок” x, функция, определяемая как наименьшее целое, большее или равное x; ëxû - “пол” x, функция определяемая как наибольшее целое, меньшее или равное x (то есть ëxû = floor(x) = [x]).

Нетрудно видеть, что в бинарном дереве с n вершинами высота равна floor(log2(n))=ëlog2(n)û (см. лемму 2 при s=2).

На представлении массивов в виде двоичных деревьев основана большая серия так называемых древовидных или турнирных сортировок. Друг от друга они отличаются способом представления исходной и сопутствующей информации, объемом дополнительно используемой памяти и т.п. Об одном из таких алгоритмов, предложенном Дж.Уильямсом и развитом Р.Флойдом, и пойдет речь ниже [3; c.6]. Называется он пирамидальным, для реализации не требует дополнительной памяти и имеет трудоемкость O(n×log2(n)).

Начнем с определения пирамиды - некоторой структуры для представления данных с отношением порядка. В нашем случае данные являются целыми или действительными числами. Пусть задан массив:

v0v1, ... ,  vn-1.                                                             (8)

 Бинарной пирамидой, или просто пирамидой, массива (8) называется непустая подпоследовательность его элементов вида

vpvp+1, ... ,  vq  (0 £ p £ q £ n-1),                                             (9)

для которой выполнено одно из следующих условий:

1.   2 × p + 1 > q;

2.   2 × p + 1 £ q          и           vj ³ v2×j+1       для      p £ j £ (q-1)/2,

                                                vj ³ v2×j+2       для      p £ j £ (q-2)/2.

Из этого определения вытекают такие утверждения:

Для всякой последовательности (8) любой фрагмент её “хвостовой части”, то есть подпоследовательность

vpvp+1, ... ,  vn-1  ( p ³ ën/2û),                                             (10)

является пирамидой. Если (8) представлена в виде бинарного дерева, то пирамида (10) при p=ën/2û соответствует всемвисячим, то есть не имеющим потомков, вершинам (см. лемму 1 при s=2).

Если последовательность (8) - пирамида, то

v0 = max(v0v1,  ... ,  vn-1).                                               (11)

Последовательность (8), представленная в виде бинарного дерева, является пирамидой тогда и только тогда, когда значение любого узла j дерева не меньше значений его возможных левого и правого потомков: 2×j+1 и 2×j+2.

Пример. Последовательность

23, 20, 11, 13, 8, 9, 8, 11, 10, 7, 1

является пирамидой. Наглядно это видно на рис.2.

 

Рис. 2. Пирамида, представленная в виде бинарного дерева

Теперь можно приступить к описанию алгоритма пирамидальной сортировки. Состоит он в реализации двух этапов. Остановимся на них подробнее.

Этап 1. Построение пирамиды. В массиве (8) “хвост”, то есть подпоследовательность (10) при p = ën/2û , как мы уже отмечали, является пирамидой. Будем наращивать (10), добавляя к ней оставшиеся элементы из (8). Пусть последовательность vj+1vj+2, ... ,  vn-1 - уже пирамида. Припишем к ней слева элемент vj:

vjvj+1, ... ,  vn-1                                                          (12)

и преобразуем (12) снова в пирамиду. Для этого “просеем” vj по соответствующей веточке двоичного представления (8). Делаем это так. Рассмотрим vj и два его возможных потомка: v2×j+1 и v2×j +2. Если vj не меньше потомков или не имеет их, то вычисления прекращаем. В противном случае обмениваем значения vj и max(v2×j + 1, v2×j +2) в соответствующих позициях дерева и “опустившийся” элемент продолжаем просеивать тем же самым способом. В конце концов, преобразованная последовательность (12) станет пирамидой. Продолжая наращивание (12), мы превратим весь массив (8) в пирамиду. При этом окажется выполненным равенство (11). Объявляем полученную пирамиду S текущей и переходим к следующему этапу.

Этап 2. Сортировка пирамиды. В текущей пирамиде T начальный элемент не меньше остальных. Поступим с ним так. Обменяем значениями концевые (начальный и конечный) элементы T и укоротим T справа на один элемент. Полученная последовательность уже может и не быть пирамидой. Применим в ней к элементу v0 процесс “просеивания”, описанный на этапе 1. Преобразованная последовательность становится пирамидой. Повторяя этот этап (n-1) раз, отсортируем T по неубыванию.

адача 5. Составить рекурсивную программу бинарной пирамидальной сортировки массива, заданного вектором v = (v0   v1  ...  vn-1).

Решение. Описанный выше алгоритм пирамидальной сортировки реализуется функциями shift(), build(), sortpiram() и piramida().

Вспомогательная рекурсивная функция shift(v, b, e) просеивает в векторе v компонент от позиции b и не далее чем до позиции e или, при представлении v в виде бинарного дерева, от вершины b до вершины e. При этом используется такой алгоритм. Если значение в b не меньше значений в вершинах-потомках, то вычисления прекращаются. В противном случае своими значениями обмениваются b и потомок с наибольшим значением. Если имеются два претендента на обмен с b, то берется потомок с меньшим номером. Далее задача рекурсивно решается на новом участке [b, e] c измененным значением индекса b (b¬2×b+1 или b¬2×b+2). Базой рекурсии является условие 2×b+1>e. Декомпозиция организуется по длине участка [b, e]. Функция shift(v, b, e) в дальнейшем будет использоваться для восстановления в векторе v пирамиды на [b, e] при условии, что свойства пирамиды на этом участке нарушены только в вершине b.

Рекурсивная функция build(v, k, e) на участке [0, e] строит в векторе v пирамиду. Предполагается, что на участке [k+1, e] в v пирамида уже построена. Рекурсия организована по параметру k.

Рекурсивная функция sortpiram(v, e) на участке [0, e] в векторе v сортирует ранее построенную пирамиду по неубыванию. Рекурсия организована по параметру e.

Головная функция piramida(v), используя функции build() и sortpiram(), строит из вектора v пирамиду, а затем сортирует её по неубыванию:

                                     (13)

                                           (14)

                                         (15)

                                        (16)

Контрольный пример:

Анализ пирамидальной сортировки показывает, что для её выполнения требуется не более 3×(n-1)×log2(n) элементарных операций типа сравнений и обменов (см. главный член в оценке леммы 3 при s=2). Подобная эффективность, реализация без дополнительной памяти и гарантированная надежность для худшего случая часто оказываются решающими факторами, заставляющими в конкретных ситуациях отдавать предпочтение именно этому способу сортировки.

Замечания.

Если в функции shift() неравенства vk < vk+1 и vb < vk заменить соответственно на vk > vk+1 и vb > vk, то функция piramida2() будет осуществлять сортировку по невозрастанию;

Незначительные изменения приведенных функций позволяют получить достаточно компактный нерекурсивный вариант алгоритма бинарной пирамидальной сортировки. Это будет сделано в следующем пункте для более общей задачи.

Home Содержание Схемы ООД Доска объявлений Поиск