Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
osnovy_programmirovanija_v_srede_lazarus.pdf
Скачиваний:
187
Добавлен:
18.03.2015
Размер:
6.53 Mб
Скачать

4.3 Динамические структуры данных

____________________________________________________________________

end;

end; { end of case }

until choose = 4;

end.

Реализация дека теперь для вас не представляет такой уж сложной задачей.

Попробуйте реализовать его самостоятельно.

4.3.6.3. Реализация двоичного дерева с помощью линейного списка

Двоичное дерево можно представить с помощью двухсвязного списка сле-

дующим образом:

type

 

PTree= ^Tree;

// Указатель на дерево

Tree= record

// Само дерево, имеет тип - запись

node: string;

// значение вершины (узла) дерева

left: PTree; // Ссылка на левое поддерево right: PTree; // Ссылка на правое поддерево end;

Здесь для разнообразия в качестве значений вершин мы взяли строки сим-

волов. Напишем рекурсивную процедуру поиска вершины по его значению:

procedure search_node(Elem: string;

ptr_tree: PTree;

var current_tree: PTree);

var

p: ^Tree; // рабочий указатель begin

380

Глава 4 Типовые алгоритмы обработки информации

____________________________________________________________________

p:= ptr_tree;

if not (p^.node = Elem) then begin

if p^.left <> nil then

search_node (Elem, p^.left, current_tree); if p^.right <> nil then

search_node (Elem, p^.right, current_tree);

end

else current_tree:= p;

end;

В процедуру передаются значение искомого узла Elem, само дерево

ptr_tree. Процедура возвращает ссылку на найденный узел current_tree.

Рекурсивная процедура удаления текущего поддерева:

procedure dispose_tree (ptr_tree: PTree); var

p: ^Tree; begin

if ptr_tree <> nil then begin

p:= ptr_tree;

if p^.left <> nil then begin

dispose_tree(p^.left); end;

if p^.right <> nil then begin

dispose_tree(p^.right);

381

4.3 Динамические структуры данных

____________________________________________________________________

end;

dispose(p);

end

end;

Рекурсивная процедура обхода двоичного дерева слева запишется на удив-

ление просто:

procedure obhod(p: PTree);

begin

if p<>nil then

begin

obhod(p^.left);

write(p^.node, ' ');

obhod(p^.right);

end;

end;

Реализуйте самостоятельно обход двоичного дерева слева по не рекурсив-

ному алгоритму 4.30!

Напишем программу ввода двоичного дерева с клавиатуры и его обхода слева:

program project1; {$mode objfpc}{$H+} uses

CRT, FileUtil; type

PTree= ^Tree; // Указатель на дерево

382

Глава 4 Типовые алгоритмы обработки информации

____________________________________________________________________

Tree= record

// Само дерево, имеет тип - запись

node: string;

// значение вершины (узла) дерева

left: PTree;

// Ссылка на левое поддерево

right: PTree;

// Ссылка на правое поддерево

end; var

ptr_tree, current_tree, root: ^Tree; p, current: ^Tree;

s: string; choose: integer;

{Процедура поиска узла}

procedure search_node(Elem: string; ptr_tree:PTree;

var current_tree:PTree);

var

p: ^Tree; begin

p:= ptr_tree; writeln(p^.node);

if not (p^.node = Elem) then begin

if p^.left <> nil then

search_node (Elem, p^.left, current_tree); if p^.right <> nil then

search_node (Elem, p^.right, current_tree);

end

else current_tree:= p;

end;

{Процедура вывода дерева на экран}

383

4.3 Динамические структуры данных

____________________________________________________________________

procedure view_tree (ptr_tree: PTree); var

p: ^Tree; begin

p:= ptr_tree; writeln(p^.node);

if p^.left <> nil then view_tree(p^.left); if p^.right <> nil then view_tree(p^.right);

end;

{Процедура удаления текущего поддерева} procedure dispose_tree (ptr_tree:PTree); var

p: ^Tree; begin

if ptr_tree <> nil then begin

p:= ptr_tree; writeln(p^.node);

if p^.left <> nil then begin

dispose_tree(p^.left); end;

if p^.right <> nil then begin

dispose_tree(p^.right); end;

384

Глава 4 Типовые алгоритмы обработки информации

____________________________________________________________________

dispose(p); end

end;

procedure obhod(p: PTree); begin

if p <> nil then begin

obhod(p^.left); write(p^.node, ' '); obhod(p^.right);

end;

end; begin

writeln(UTF8ToConsole('введите номер или имя вершины'));

readln(s);

new(current);

root:= current;

current^.node:= s;

current^.left:= nil;

current^.right:= nil;

repeat

writeln;

writeln(UTF8ToConsole('Корень текущего подерева: '),

current^.node);

writeln(UTF8ToConsole('Выберите нужное действие:')); writeln(UTF8ToConsole('1-ввод левого поддерева')); writeln(UTF8ToConsole('2-ввод правого поддерева'));

writeln(UTF8ToConsole('3-сделать корень поддерева текущим'));

writeln(UTF8ToConsole('4-просмотреть дерево'));

385

4.3 Динамические структуры данных

____________________________________________________________________

writeln(UTF8ToConsole('5-удалить текущее поддерево'));

writeln(UTF8ToConsole('6-обход дерева слева'));

writeln(UTF8ToConsole('7-выход из программы')); readln(choose);

case choose of

1: begin {Создание левого поддерева} if current^.left= nil then

new(p) else

p:= current^.left; writeln(UTF8ToConsole('введите номер или имя вершины')); readln(s);

p^.node:= s; p^.left:= nil; p^.right:= nil; current^.left:= p;

end;

2: begin {Создание правого поддерева} if current^.right= nil then

new(p) else

p:= current^.right; writeln(UTF8ToConsole('введите номер или имя вершины')); readln(s);

p^.node:= s; p^.left:= nil; p^.right:= nil; current^.right:= p;

end;

386

Глава 4 Типовые алгоритмы обработки информации

____________________________________________________________________

3: begin {Поиск нужной вершины} writeln(UTF8ToConsole('введите номер или имя вершины')); readln(s);

current_tree:= nil; ptr_tree:= root;

search_node (s, ptr_tree, current_tree); if current_tree <> nil then

current:= current_tree; end;

4: begin {Вывод введенного дерева на экран} ptr_tree:= root; view_tree(ptr_tree);

end;

5: begin {Удаление поддерева} writeln(UTF8ToConsole('введите букву L для')); writeln(UTF8ToConsole('удаления левого поддерева')); writeln(UTF8ToConsole('или любой символ для')); writeln(UTF8ToConsole('удаления правого поддерева')); readln(s);

if (s= 'l') or (s= 'L') then begin {Удаление левого поддерева} ptr_tree:= current^.left;

current^.left:= nil; dispose_tree(ptr_tree);

end else

begin {Удаление правого поддерева} ptr_tree:= current^.right; current^.right:= nil;

387

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]