Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Пособие часть1.doc
Скачиваний:
22
Добавлен:
01.03.2025
Размер:
6.94 Mб
Скачать

3.6.2. Ссылочная реализация на основе массива

В разделе 2.5 рассматривался способ ссылочной реализации линейного списка на основе массива (вектора). Вспомним, что в этом случае элементы могут располагаться в массиве не по порядку, но каждый элемент содержит одну или две ссылки на своих соседей. Ссылки обычно представляют собой индексы элементов массива, следовательно, если применять такой принцип к бинарному дереву, то каждый узел можно представить как структуру (запись), в которой хранятся данные и два индекса — ссылка на левого и правого сына (пустой ссылке обычно соответстствует несуществующий индекс, например, 0 или -1).

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

Описание такой структуры может выглядеть, например, так:

struct node // структура для одного узла дерева

{ type_of_data data; // данные

int left, right; // индекс левого и правого сына

};

const int maxlength=10000; //максимальный размер массива

node bintree[maxlength]; //массив для бинарного дерева

int topfree; //ссылка на начало свободной области (индекс)

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

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

Поясним процесс формирования бинарного дерева на простом примере. Пусть необходимо сформировать то же самое дерево, изображенное на рис.3.10,а, используя массив из 10 элементов.

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

Если обозначить пустую ссылку как -1, то содержимое массива будет таким, как изображено в табл. 3.3, а ссылка topfree имеет значение 7, если нумерация элементов массива начинается с нуля.

Таблица 3.3.

Реализация дерева из рисунка 3.10,а с помощью массива

Индекс в массиве

Значение data

Левый сын left

Правый сын right

Примечание

0

f

-1

-1

Лист f

1

c

-1

0

Узел c

2

g

-1

-1

Лист g

3

e

-1

2

Узел e

4

d

-1

-1

Лист d

5

b

4

3

Узел b

6

a

5

1

Корень дерева a

7

8

Начало списка свободных элементов

8

9

Свободный элемент

9

-1

Последний свободный элемент

Реализацию приведенных в спецификации базовых функций можно выполнить самостоятельно по аналогии с разделом 2.5. При этом интересно реализовать такие дополнительные функции как вставка и удаление узлов.