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

Атд «Дерево» и «Лес»

Рассмотрим функциональную спецификацию структуры данных дерева c узлами типа α: Tree ( α ). При этом лес деревьев Forest ( Tree ( α ) ) определим как L_list ( Tree ( α ) ) через уже известную структуру линейного списка L_list с базовыми функциями Cons, Head, Tail, Null (см.1.6). Базовые операции с деревом задаются набором функций:

1) Root : Tree  α;

2) Listing : Tree  Forest;

3) ConsTree : α  Forest  Tree

и аксиомами, справедливыми для любого u типа α; любого f типа Forest ( Tree ( α ) ); любого t типа Tree ( α ) ):

А1) Root ( ConsTree ( u , f ) ) = u;

А2) Listing ( ConsTree ( u , f ) ) = f;

А3) ConsTree ( Root ( t ) , Listing ( t ) ) = t.

Здесь функции Root и Listing - селекторы: Root выделяет корень дерева, а Listing выделяет лес поддеревьев корня данного дерева. Конструктор ConsTree порождает дерево из заданных корня и леса поддеревьев.

Атд «Бинарное дерево»

Далее введем АТД BinTree — сокращенно BT( α ), где α  — тип данных, которые хранятся в узлах бинарного дерева . Считаем, что значение типа BT есть либо  (пустое бинарное дерево), либо значение типа NonNullBT( α ). Тогда базовые операции типа BT ( α ) задаются набором функций:

0)  :  BT(α);

1) Root: NonNullBT(α)  α;

2) Left: NonNullBT (α ) BT(α);

3) Right: NonNullBT  BT(α);

4) ConsBT: α  BT(α)  BT(α)  NonNullBT(α);

5) IsNull: BT(α)  Boolean;

и набором аксиом, справедливых для всех  u типа α, b типа NonNullBT ( α ), b1, b2 типа BT ( α ) ):

A1) IsNull (  ) = true;

A1') IsNull ( b ) = false;

A2) IsNull ( ConsBT ( u , b1 , b2 ) ) = false;

A3) Root ( ConsBT ( u , b1 , b2 ) ) = u;

A4) Left ( ConsBT ( u , b1 , b2 ) ) = b1;

A5) Right ( ConsBT ( u , b1 , b2 ) ) = b2;

A6) ConsBT (Root ( b ) , Left ( b ) , Right ( b )) = b.

Здесь функции Root, Left и Right  селекторы: Root выделяет значение корня бинарного дерева, а Left и Right  его левое и правое поддеревья соответственно. Конструктор ConsBT порождает бинарное дерево из заданных узла и двух бинарных деревьев — его сыновей. Предикат IsNull  индикатор, различающий пустое и непустое бинарные деревья.

Используя рекурсивные вызовы представленных базовых функций, можно реализовать любые действия с бинарными деревьями. Например, дерево, которое изображено на рис. 3.10,а, в следующем разделе будет использоваться как пример для реализации. Если обозначить его t, то можно записать следующее полное левое скобочное представление (для тренировки изобразите дерево, не заглядывая в рисунок):

t=a(b(d ( ) e(g( ) )) с(  f(  )))

Его можно сформировать, используя функцию consbt, следующим образом:

t=consbt(a, consbt(b, consbt(d,,),consbt(e,consbt(g,,),)), consbt(c,,consbt(f,,)))

Однако, для того, чтобы добавить или удалить узел (а это типовые операции в большинстве применений деревьев), придется сначала «разобрать» дерево с помощью селекторов, а затем «собрать» с помощью конструктора. Например, для того, чтобы удалить узел g из уже сформированного дерева t, можно использовать следующую последовательность операций

t=consbt(root(t), consbt(root(left(t)), left(left(t), consbt(root(right(left(t))), ,)), right(t))

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

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