4877

Пирамидальная сортировка и способы ее построения в программировании

Лекция

Информатика, кибернетика и программирование

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

Русский

2012-11-28

73.5 KB

47 чел.

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

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

Рис 1. Пример бинарного дерева.

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

Рис 2. Пример пирамиды.

Сортировка начинается с построения пирамиды, содержащей все элементы исходной последовательности. Ясно, что максимальный элемент окажется в вершине дерева, поскольку все её потомки обязательно должны быть меньше. Затем, вершина пирамиды записывется в конец последовательности, а пирамида с удаленным максимальным элементом переформировывается. В результате, на её вершине оказывается максимальный из оставшихся элементов, он записывается на соответствующее место, и процедура продолжается до тех пор, пока пирамида не опустеет.

Таким образом, основную нагрузку алгоритма несут две процедуры: начальное построение пирамиды и переформирование пирамиды на каждом шаге. Для построения пирамиды можно воспользоваться её свойством – у каждого внутреннего узла ровно два непосредственных потомка, за исключением, быть может, одного узла на предпоследнем уровне. Следовательно, можно пронумеровать узлы, начиная с вершины по правилу: если узел имеет номер i, то его потомкам назначим номера 2*i и 2*i+1. В результате все узлы пирамиды получат уникальные номера в диапазоне 1 ~ N, что дает возможность хранить пирамиду в виде последовательности:

Рис 3. Списочное представление пирамиды (см рис.2).

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

  1.  если элемент не имеет потомков, то конец;
  2.  иначе меняем местами значения элемента и максимального из двух его непосредственных потомков;
  3.  переходим к изменившемуся потомку и выполняем для него ту же процедуру с шага 1.

Такой подход к перестроению пирамиды можно использовать также и для построения её начального состояния: любые два элемента можно считать потомками некоторого свободного узла. Поскольку все элементы являются «листьями», со второй половиной последовательности можно ничего не делать. Начиная с набора листовых элементов, можно соединять их попарно до тех пор, пока не будет сформирована общая большая пирамида. Первый добавляемый корень в последовательности из N элементов будет иметь индекс N / 2 - 1. В итоге алгоритм начального построения пирамиды будет заключаться в последовательном применении процедур «просеивания вниз» ко всем элементам с индексами от N / 2 - 1 до 0.

Рис. 4. Пример применения процедуры «просеивания вниз»

к измененному корневому элементу пирамиды.

// Функция "просеивает" элемент номер i вниз в пирамиде heap размера size

void fixHeap( double * heap, int i, const int size )

{   

   // Индекс максимального элемента в текущей тройке элементов:

   int maxIdx = i ;

   // Значение текущего элемента:

   double value = heap[i];

     

   while ( true )

   {

      int childIdx = i * 2 + 1; //Индекс левого потомка

      

      // Если есть левый потомок и он больше текущего элемента,

      if ( ( childIdx < size ) && ( heap[ childIdx ] > value ) )

         maxIdx = childIdx; //  то он считается максимальным

           

       childIdx = i * 2 + 2; //Индекс правого потомка

       

       // Если есть правый потомок и он больше максимального,

       if ( ( childIdx < size ) && ( heap[ childIdx ] > heap[ maxIdx ] ) )

           maxIdx = childIdx; //  то он считается максимальным

       // Если текущий элемент является максимальным из трёх

       // (т.е. если он больше своих детей), то конец:

       if ( maxIdx == i )

          break;

       

       // Меняем местами текущий элемент с максимальным:

       heap[i] = heap[ maxIdx ];

       heap[ maxIdx ] = value;

       

       // Переходим к изменившемуся потомку

       i = maxIdx;

   }

}

// Пирамидальная сортировка массива heap размера size

void heapSort( double * heap, int size )

{   

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

   for( int i = size / 2 - 1; i >= 0; --i )

      fixHeap( heap, i, size );

   

   // Сортировка с помощью пирамиды

   while( size > 1 ) // пока в пирамиде больше одного элемента

   {

       --size; // Отделяем последний элемент

       // Обмениваем местами корневой элемент и отделённый:

       double firstElem = heap[0];

       heap[0] = heap[ size ];

       heap[ size ] = firstElem;

       

       // "Просеиваем" новый корневой элемент вниз:

       fixHeap( heap, 0, size );

   }

}


A

B

C

E

D

G

H

12

10

5

9

7

3

1

2

11

8

6

4

12

1

10

2

11

3

5

4

9

5

8

6

6

7

1

8

2

9

7

10

3

11

4

12

6

10

5

9

7

3

1

2

11

8

6

4

11

10

5

9

7

3

1

2

6

8

6

4

11

10

5

9

7

3

1

2

8

6

6

4


 

А также другие работы, которые могут Вас заинтересовать

28841. Развитие отечественной психологии в 20-40-е годы ХХ века 51.5 KB
  Развитие отечественной психологии в 2040е годы ХХ века Октябрьская революция оказала значительное влияние на развитие российской науки в целом и психологии в частности. С другой стороны молодое Советское государство начало последовательно оказывать помощь психологической науке создаются институты с исследовательскими лабораториями Двадцатые годы стали временем рождения советской психологии.задачи психологии: 1. вычленяются два основных методологических принципа марксистской психологии: материализм психика продукт деятельности...
28842. Педология в Советской России: основные направления работы достижения 44.5 KB
  Генетический принцип означал принятие во внимание динамики и тенденции развития. Ребенка можно изучать лишь с учетом его социальной среды которая оказывает влияние не только на психику но часто и на антропоморфические параметры развития. Наука о ребенке должна быть не только теоретической но и практической Общие моменты развития педологии В россии начала распространяться в нач 20 в. Разница между этими подходами была не только во взглядах на роль наследственности и среды но и насколько биологические механизмы лежащие в основе психического...
28843. Культурно-историческая теория Л.С. Выготского 48 KB
  Филосовская основа Марксизм: Считалось что Человек природное существо но его природа социальна и поэтому человека его психику новообразования нужно рассматривались как продукт общественноисторического развития. Только в процессе общественной жизни человека возникли сложились и развились его новые потребности а самые природные потребности человека в процессе его исторической развития изменились. С точки зрения динамики развития он разделил детство на критические и литические периоды дав качественную характеристику кризисов....
28844. Психологическая теория деятельности. Виды деятельности 44 KB
  Психологическая теория деятельности. Виды деятельности. Именно он первым из психологов поставил вопрос о необходимости психологического изучения деятельности и человека как деятеля как субъекта деятельности ввёл в психологических обиход сам термин деятельность. Анализируя психологическое содержание поведенческого акта деятельности; действия он предпочитает рассматривать его с позиций известной бихевиористической схемы S R.
28845. Развитие детской и дифференциальной психологии в советской России 66 KB
  привели к необходимости развития отечественной науки. Басов заложил основы нового понимания механизмов психического развития которые были развиты в концепции Выготского. Выготский впервые перешел от утверждения о важности среды для развития к выявлению конкретного механизма этого влияния среды который собственно и изменяет психику ребенка приводя к появлению специфических для человека высших психических функций ВПФ. При этом знаки будучи продуктом общественного развития несут на себе отпечаток культуры того социума в котором растет...
28846. История психологии как наука 52 KB
  История психологии как наука Предмет История психологии это особая отрасль знания имеющая собственный предмет. Его нельзя смешивать с предметом самой психологии как науки. В истории психологии изучается не сама психическая реальность а представления о ней какими они были на разных этапах развития науки. История психологии описывает и объясняет как эти факты и законы открывались.
28847. Психологические учения античности 66 KB
  Психологические учения античности Понимание души в донаучных представлениях о переселении душ орфической и тотемной религии их влияние на античную психологию: понятия анимизма гилозоизма. Деятельность животного или человека объясняется присутствием этой души а его успокоение во сне или в смерть ее отсутствием; сон или транс временное а смерть постоянное отсутствие души. анима душа дух одухотворение окружающего мира утверждение что за всеми явлениями реальности живыми и неживыми стоят духи души. Начало понимания связи...
28848. Характеристика психологических учений средневековья 67 KB
  Главное качество души единство ввёл принцип холизма душа и разум едины. Бог поставляет в мировой разум идеи душа получает идеи и передает человеку в материю материя чувственный мир. Душа производит все живые существа вдохнув в них жизнь. Душа человека находится в связи с Душой божественной и чувственным миром.
28849. Особенности психологических воззрений в новое время 55 KB
  встаёт проблема соотношения физического и психического опыт становится основным методом изучения природы в том числе и человека. Задача науки это покорение природы и усовершенствование человека. Он отверг душу как силу организующую поведение и управляющую им открыв путь к объективному изучению явлений органической природы. интуитивное знание истинное объективное содержаться в разуме и открываются интуитивно Спиноза утверждал существование единой неделимой и вечной субстанции преодоление дуализма Декарт Бога или Природы.