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

2 семестр / Методические материалы / metodicheskie-ukazaniia-po-teme-15

.pdf
Скачиваний:
3
Добавлен:
20.05.2025
Размер:
829 Кб
Скачать

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

Пусть необходимо отсортировать по убыванию массив из 8-и элементов:

9, 13, 3, 12, 6, 5, 8, 10.

Представим этот массив в виде двоичного дерева, у которого уровни заполняются последовательно слева направо:

0 1 2 3 4 5 6 7

9

13

3

12

6

 

5

8

10

нелистовые

 

 

листья

 

 

 

 

0

9

 

 

 

– не пирамида

 

1

13

 

 

 

2

3

 

3

12

4

6

 

5

5

6

8

7 10

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

Применим реализацию алгоритма пирамидальной сортировки, описанную выше. После вызова функции TreeSort() сначала выполняется построение пирамиды из имеющегося массива с помощью цикла:

for (i=k-1; i>=0; i--)

TreeRebuild(i,n-1); /*построение пирамиды (только один раз)*/

при значениях переменных: n=8, k=4. На каждой итерации цикла вызывается функция TreeRebuild() для каждой нелистовой вершины:

TreeRebuild(3,7);

TreeRebuild(2,7);

TreeRebuild(1,7);

TreeRebuild(0,7);

После вызова TreeRebuild(3,7) на 1-й итерации цикла поменяются местами узлы 12 и 10 (и соответствующие им элементы массива A[3] и A[7]):

0 1 2 3 4 5 6 7

9

13

3

10

6

 

5

8

12

нелистовые

 

 

листья

 

 

 

 

0

9

 

 

 

– не пирамида

 

1

13

 

 

 

2

3

 

3

10

4

6

 

5

5

6

8

7 12

11

После вызова TreeRebuild(2,7) на 2-й итерации цикла изменений не произойдет, поскольку для узла 3 (элемент массива A[2]) выполняется условие пирамиды.

После вызова TreeRebuild(1,7) на 3-й итерации цикла поменяются местами узлы 13 и 6 (и соответствующие им элементы массива A[1] и A[4]):

0 1 2 3 4 5 6 7

 

9

6

3

10 13

5

8

12

 

нелистовые

 

листья

 

 

 

 

 

0

9

 

 

– не пирамида

 

 

1

6

 

 

2

3

 

 

3

10

4

13

5

5

6

8

7

12

 

 

 

 

 

 

 

Наконец, после заключительного вызова TreeRebuild(0,7) на 4-й итерации цикла поменяются местами три узла: 9, 3 и 5 (и соответствующие им элементы массива A[0], A[2] и A[5]):

0 1 2 3 4 5 6 7

3

6

5

10 13

9

8

12

нелистовые

 

листья

 

 

 

 

0

3

 

 

– пирамида

 

1

6

 

 

2

5

 

3

10

4

13

5

9

6

8

7 12

Полученный массив является пирамидой – для всех его элементов выполняются условия пирамиды.

Построение пирамиды проводится однократно и имеет линейный порядок сложности O(n).

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

После построения пирамиды в корне дерева (первый элемент массива A[0]) находится минимальный элемент массива 3. Помещаем его в отсортированную часть массива. Поскольку выполняется сортировка по убыванию, то отсортированную часть следует расположить в конце массива.

Поменяем местами первый и последний элементы: A[0] и A[7]. При этом дерево становится на один элемент меньше и в нем нарушается привило пирамиды:

12

0 1 2 3 4 5 6 7

12

6

5

 

10 13

9

 

8

3

нелистовые

 

 

листья

 

 

отсорт.часть

 

 

 

 

0

12

 

 

 

– не пирамида

 

 

 

 

 

 

 

 

 

 

1

6

 

 

 

 

2

5

 

3

10

 

4

13

5

9

 

6

8

Значение элемента 12, попавшего в корень дерева, необходимо «протолкнуть» через пирамиду – повторить построение пирамиды для элемента A[0] с помощью функции TreeRebuild().

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

В описанной выше реализации алгоритма пирамидальной сортировки в функции TreeSort() перестановка элементов из корня в отсортированную часть и проталкивание через пирамиду выполняется с помощью цикла:

for (i=n-1; i>=1; i--) {

swap(&A[0],&A[i]); /*перестановка 0-го и i-го элементов*/ TreeRebuild(0,i-1); /* «проталкивание» i-го элемента*/

}

При n=8 выполняется 7 итераций цикла, на каждой из которых вызываются:

­функция swap() для перестановки корня дерева и последнего элемента,

­функция TreeRebuild() для проталкивания нового корня дерева через пирамиду.

swap(&A[0],&A[7]);

/* Первая

*/

TreeRebuild(0,7);

/* итерация. */

...

/* ...

*/

swap(&A[0],&A[1]);

/*

Седьмая

*/

TreeRebuild(0,1);

/*

итерация. */

На 1-й итерации цикла при проталкивании элемента 12 через пирамиду поменяются местами три узла: 12, 5 и 8 (и соответствующие им элементы массива A[0], A[2] и A[6]). После выполнения 1-й итерации цикла:

0 1 2 3 4 5 6 7

5

6

8

10 13

9

12

3

нелистовые

 

 

листья

 

 

отсорт.часть

 

 

 

 

0

5

 

 

 

– пирамида

 

 

 

 

 

 

 

 

 

 

1

6

 

 

 

 

2

8

 

3

10

 

4

13

5

9

 

6

12

13

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

На 2-й итерации цикла после перестановки корня дерева и последнего элемента в дереве останется 6 элементов, которые не образуют пирамиду:

0 1 2 3 4 5 6 7

12

6

8

 

10 13

9

5

3

нелистовые

 

листья

 

отсорт.часть

 

 

 

 

0

12

 

 

– не пирамида

 

 

 

 

 

 

 

 

 

1

6

 

 

 

2

8

 

3

10

 

4

13

5

9

 

 

При проталкивании элемента 12 через пирамиду поменяются местами три узла: 12, 6 и 10 (и соответствующие им элементы массива A[0], A[1] и A[3]). После выполнения 2-й итерации цикла:

0 1 2 3 4 5 6 7

6

10

8

12 13

9

5

3

нелистовые

листья

 

отсорт.часть

 

 

 

0

6

 

 

– пирамида

 

 

 

 

 

 

 

 

1

10

 

 

2

8

 

3

12

4

13

5

9

 

 

На 3-й итерации цикла после перестановки корня дерева и последнего элемента в дереве останется 5 элементов, которые не образуют пирамиду:

0

1

2

3

4

5

6

7

9

10

8

12 13

6

5

3

нелистовые

 

листья

отсорт.часть

 

 

 

0

9

 

 

– не пирамида

 

 

 

 

 

 

 

 

1

10

2

8

3

12

4

13

 

При проталкивании элемента 9 через пирамиду поменяются местами только два узла: 9 и 8 (и соответствующие им элементы массива A[0] и A[2]). После выполнения 3-й итерации цикла:

14

0

1

2

3

4

5

6

7

8

10

9

12 13

6

5

3

нелистовые

 

листья

отсорт.часть

 

 

 

0

8

 

 

– пирамида

 

 

 

 

 

 

 

 

1

10

2

9

3

12

4

13

 

Аналогично – на остальных итерациях проталкивания элемента через пирамиду.

После выполнения 4-й итерации цикла:

0

1

2

3

4

5

6

7

9

10 13 12

8

6

5

3

нелистовые

листья

отсорт.часть

 

 

 

 

 

0

9

 

 

1

10

2

13

3 12

цикла переноса корня и

– пирамида

После выполнения 5-й итерации цикла:

0 1 2 3 4 5 6 7

 

10

12

13

9

8

6

5

3

 

 

 

 

 

 

 

 

 

 

 

нелист. листья

отсортированная часть

 

 

 

 

 

0

10

 

 

– пирамида

 

 

 

 

 

 

 

 

 

1

12

 

 

2

13

 

После выполнения 6-й итерации цикла:

0

1

2

3

4

5

6

7

12 13 10

9

8

6

5

3

нелист. лист

отсортированная часть

 

 

 

 

0

12

 

– пирамида

 

 

 

 

 

 

 

1 13

15

Наконец, после выполнения заключительной 7-й итерации цикла дерево состоит из одного элемента – корня, который является листом:

0

1

2

3

4

5

6

7

13 12 10

9

8

6

5

3

лист

 

отсортированная часть

 

 

 

 

 

0

13

 

– пирамида

При этом весь массив является отсортированным по убыванию.

Повторяющаяся процедура перестановки корня в отсортированную часть и проталкивания элемента через пирамиду имеет порядок сложности O(n·log n).

Общий порядок сложности метода пирамидальной сортировки складывается из оценок сложности построения пирамиды и проталкивания через нее элементов: O(n) + O(n·log n) O(n·log n).

16