- •2. Двоичные деревья
- •Inf : Elem;
- •3. Основные операции с двоичными деревьями
- •Inf_s : Tree;
- •Var p:Stack;
- •Var p:Stack;
- •Var start : Stack; flag : boolean;
- •Var I : integer;
- •Var m : integer;
- •Var k : integer;
- •4. Дерево поиска ( сортировки )
- •Inf : integer;
- •Var X : integer; Root : Tree;
- •Var flag : boolean;
- •InTree(Root,X)
- •Var q : Tree;
- •Var q : Tree;
- •Var s: Tree;
- •5. Сбалансированные деревья
- •Var p : Tree;
- •Var I : integer;
Inf_s : Tree;
next : Stack
end;
Процедура добавления в стек start элемента T :
procedure Push (var start:Stack; T : Tree);
Var p:Stack;
begin
new(p);
p^.inf_S:=T;
p^.next:=start;
start:=p
end;
Процедура извлечения из стека start элемента T :
procedure Pop (var start:Stack; var T : Tree);
Var p:Stack;
begin
p:=start;
T:=start^.inf_S;
start:=start^.next;
dispose(p)
end;
Функция проверки, является ли стек start пустым :
function Empty (start:Stack): boolean;
begin
Empty:=start=nil
end;
Процедура префиксного обхода дерева :
procedure PrefOrd (T : Tree);
Var start : Stack; flag : boolean;
begin
start:=nil; { очистить стек }
flag:=true;
while flag do
begin
{ операция обработки узла дерева , например, writeln( T^.inf );}
{ перейти к следующему узлу }
if T^.L <> nil then { есть левая ветвь }
begin
{ если правая ветвь есть, то ссылку на нее добавить в стек }
if T^.R <> nil then Push(start,T^.R);
T:=T^.L { по левой ветви вниз }
end
else
if T^.R <> nil then { есть правая ветвь }
T:=T^.R { по правой ветви вниз }
else { нет обеих ветвей }
begin
if Empty(start) then { если стек пуст }
flag:=false { конец обхода }
else { извлечь ветвь из стека и идти по ней }
Pop(start,T)
end
end {while}
end; { PrefOrd }
Упражнение 3.1. Описать нерекурсивную процедуру
а) инфиксного обхода дерева;
б) постфиксного обхода дерева.
3.2 Обработка узлов дерева
Рассмотрим двоичное дерево, узлы которого содержат в информационной части целые числа. Назовем их элементами дерева.
Пример 3.5. Описать процедуру вывода дерева, выделяющую каждый уровень h с помощью соответствующего отступа.
procedure PrintTree(T : Tree; h : integer );
Var I : integer;
begin
if T <> nil then
begin
PrintTree (T^.R, h+1);
for i:=1 to h do write(‘ ‘);
writeln( T^.inf );
PrintTree (T^.L, h+1);
end
end; { PrintTree }
Здесь используется не инфиксный обход, а обход справа налево, чтобы дерево не выдавалось в зеркальном отображении.
Так как корень дерева Root находится на нулевом уровне, то обращение к процедуре PrintTree будет иметь вид
PrintTree(Root,0)
Пример 3.6. Описать процедуру MaxEl , определяющую наибольший элемент непустого дерева T.
Алгоритм MaxEl использует префиксный обход дерева: наибольший элемент находится или в узле, или в его левом поддереве, или в его правом поддереве.
procedure MaxEl(T : Tree; var max : integer);
Var m : integer;
begin
if T <> nil then
begin
max:=T^.inf;
if T^.L <> nil then
begin
MaxEl(T^.L, m);
if m > max then max:=m
end;
if T^.R <> nil then
begin
MaxEl(T^.R, m);
if m > max then max:=m
end
end
end; { MaxEl }
Пример 3.7. Описать рекурсивную процедуру Leaf подсчета количества k листьев дерева.
procedure Leaf( T : Tree; var k : integer);
begin
if T <> nil then
if (T^.L=nil) and (T^.R=nil) then
k:=k+1
else
begin
Leaf(T^.L,k);
Leaf(T^.R,k)
end
end; { Leaf }
Количество List листьев дерева Root можно определить, обратившись к процедуре Leaf :
List:=0; Leaf(Root,List);
Если описать реализацию в виде функции, то не придется заботиться о присваивании нуля параметру–результату перед ее вызовом.
function fLeaf ( T: Tree ) : integer;
begin
if T=nil then fLeaf:=0
else
if (T^.L=nil) and (T^.R=nil) then
fLeaf:=1
else fLeaf:= fLeaf(T^.L)+fLeaf(T^.R)
end {fLeaf};
Пример 3.8. Описать рекурсивную функцию Double, которая проверяет, есть ли в дереве T хотя бы два одинаковых элемента.
Один из вариантов проверки состоит в использовании функции Count подсчета числа вхождений заданного элемента El в дерево T. Функция Double поочередно проверяет число вхождений текущего значения T^.inf в дерево: если число вхождений больше 1, то результат проверки – истина, если нет, то такая ситуация может возникнуть в левом поддереве или в правом поддереве.
function COUNT(T : Tree; El :integer ) : integer;