type
TInfo : Integer;
PNode ^= TNode;
TNode = record
Info : TInfo;
Left, Right : PNode;
end;
procedure createNode(var N : PNode; I : TInfo); // Создание и инициализация элемента
begin
new(N);
N^.Info := X;
N^.Left := NIL;
N^.Right := NIL;
end;
procedure Insert(Root : PNode; X : TInfo); // Вставка элемента
begin
If Root = NIL then createNode(Root, X) // Создаем новый узел дерева
else
with Root^ do begin
if Info < X then Insert(Right, X)
else
if Info > X then Insert(Left, X)
else {Действий, производимые в случае повторного внесения элемента в дерево}
end;
end;
function Find(Root : PNode; X : TInfo); // Поиск элемента. Возвращает адрес узла с найденным элементом; если элемент в дереве не найден, возвращается nil)
begin
if Root := NIL then Find := NIl
else
If X = Root^.Info then Find := Root
else
If X < Root^.Info then Find := Find(Root^.Left, X)
else Find := Find(Root^.Right, X);
end;
function DeleteMin(Root : PNode): TInfo; // Удаляет наименьший элемент непустого дерева Root и возвращает значение удаленного элемента
var WasRoot: PNode;
begin
if Root^.Left = nil then begin
DeleteMin := Root^.Info; // результат функции
WasRoot := Root; // Запоминаем узел для последующего удаления
Root := Root^.Right; // Двигаемся дальше
Dispose(WasRoot); // Удаляем бывший корень
end
else {узел Root имеет левого "сына"}
DeleteMin := DeleteMin(Root^.Left);
end;
end;
procedure Remove(Root : PNode; X : TInfo); // Процедура удаления элемента
var WasNext: PNode;
begin
if Root <> NIL then
if X < Root^.Info then Remove(Root^.Left, X)
else
if X > Root^.Info then Remove(Root^.Right, X)
else
if (Root^.Left = NIL) and (Root^.Right = NIL) then begin // Нет сыновей
Dispose(Root);
Root := NIL;
end
else if Root^.Left = NIL then begin
WasNext := Root^.Right;
Dispose(Root);
Root := WasNext;
end
else if Root^.Right = NIL then begin
WasNext := Root^.Left;
Dispose(Root);
Root := WasNext;
end
else Root^.Info := DeleteMin(Root^.Right); // У удаляемого элемента есть оба "сына"
end;
procedure PreOrder(Root: PNode); // Прямой обход
begin
If Root = NIL then break;
Write(Root^.Info);
PreOrder(Root^.Left);
PreOrder(Root^.Right);
end;
procedure PostOrder(Root: PNode); // Обратный обход
begin
If Root = NIL then break;
PostOrder(Root^.Left);
Write(Root^.Info);
PostOrder(Root^.Right);
end;
procedure ReverseOrder(Root: PNode); // Концевой обход
begin
If Root = NIL then break;
ReverseOrder(Root^.Left);
ReverseOrder(Root^.Right);
Write(Root^.Info);
end;