
- •1Введение
- •2Сортировки
- •2.1Сортировки массивов
- •2.2Сортировка простым включением
- •2.3Сортировка простым выбором
- •2.4Сортировка простым обменом
- •2.5Сравнение простых сортировок
- •2.6 Сортировка шелла
- •2.7Пирамидальная сортировка
- •2.8Быстрая сортировка
- •2.9Поиск медианы и квантилей
- •2.10Сравнение сортировок
- •3Поиск подстроки в строке
- •3.1Поиск в строке
- •3.2Простой поиск в строке
- •3.3Поиск в строке. Алгоритм боуера-мура
- •4Генерация перестановок
- •4.1Генерация перестановок последовательности натуральных чисел
- •4.2Генерация перестановок элементов в антилексикографическом порядке
- •4.3Генерация перестановок за одну транспозицию элементов
- •4.4Генерация перестановок за одну транспозицию соседних элементов
- •5Генерация подмножеств
- •5.1Генерация всех подмножеств множества
- •5.2Генерация m -элементных подмножеств множества натуральных чисел
- •Var m: integer; {Размер подмножества}
- •Var I, j, p: integer;
- •5.3Генрация k-компонентных выборок на множестве {0, 1}
- •Var k: integer; {Количество нулей в кортеже}
- •I: integer;
- •Var I, j, p: integer;
- •If Finish then Break {Exit};
- •6Генерация разбиений
- •6.1Разбиение целых чисел
- •Var I, j: integer;
- •Var j: integer;
- •Var I, j, k: integer;
- •Var d, l, Sum: integer;
- •6.2Разбиение множеств
- •/1, 2, 3/ И /4/ затем /1, 2/ и /3, 4/ и т.Д. }
- •I, j, k, r, s: integer;
- •If not Flag2 then
- •If Flag1 then
- •If Forvd[j] then { j движется вперед}
- •7Обходы бинарных деревьев
- •7.1Процедуры прохождения бинарных деревьев
- •8Поиск на бинарных деревьях
- •8.1Процедуры поиска на бинарных деревьях
- •Рекомендованная литература
7.1Процедуры прохождения бинарных деревьев
Ниже приводятся процедуры прохождения бинарных деревьев для случая узлового представления таких деревьев.
type TPNode= ^TNode;
TNode = record
Inf: array [1..10] Of Char;
Left, Right: PNode;
end;
var Rut: TPNode;
Процедура прохождения БД в прямом порядке (ПБДПП).
procedure PBDPP (PTree: TPNode);
begin
if PTree <> Nil then
begin
Writeln (PTree^.Inf);
PBDPP (PTree^.Left);
PBDPP (PTree^.Right)
end;
end;
Процедура прохождения БД в симметричном порядке (ПБДСП).
procedure PBDSP (PTree: TPNode);
begin
if PTree <> Nil then
begin
PBDSP (PTree^.Left);
Writeln (PTree^.Inf);
PBDSP (PTree^.Right)
end;
end;
Процедура прохождения БД в обратном порядке (ПБДОП).
procedure PBDOP (PTree: TPNode);
begin
if PTree <> Nil then
begin
PBDOP (PTree^.Left);
PBDOP (PTree^.Right)
Writeln (PTree^.Inf);
end;
end;
Процедура прохождения БД в горизонтальном порядке (ПБДГП).
Согласно приведенному алгоритму для всех узлов уровня К необходимо запоминание всех их сыновей т.е. узлов уровня К + 1. В предыдущих процедурах на каждом шаге выбирался только один из сыновей, который затем сохранялся в стеке, создаваемом рекурсивной процедурой. В разрабатываемой процедуре на каждом шаге необходимо запоминать всех потомков всех узлов уровня К. Для реализации этого действия потребуется дополнительная структура данных, способная динамически расти и позволяющая заносить и выбирать узлы в порядке их поступления, а это очередь, реализованная с помощью списка.
Введем необходимые дополнительные типы данных, переменные и процедуры работы с очередью. Элементами очереди являются указатели на соответствующие узлы дерева, а не их содержимое. Это позволяет экономить память в случае, если объем информации в узле дерева требует значительный объем памяти.
type TPNode= ^TNode;
TNode = record
Inf: array [1..10] Of Char;
Left, Right: PNode;
end;
TPointQueue = ^TQueue;
TQueue = record
PNTree: TPNode;
Next: TPointQueue;
end;
var Rut: TPNode;
BeginQueue, EndQueue, BeginList: TpointQueue;
(* процедура занесения элемента в очередь *)
procedure InsertQ (var BegQue, EndQue: TPointQueue; NewElm: PNode);
var WP: TpointQueue;
begin
New (WP);
WP ^.PNTree : = NewElm;
WP ^.Next: = Nil;
if EndQue = Nil then
begin
BegQue: = WP (* cлучай первого элемента *)
EndQue: = WP;
end;
else
begin
EndQue^.Next: = WP;
EndQue: = WP;
end;
end;
(* функция проверки очереди на пустоту *)
function EmptyQ (BegQue: TPointQueue): boolean;
begin
if BegQue = Nil then Empty: = True
else Empty: = False
end;
{процедура выполняет горизонтальный обход дерева и возвращает указатель на начало очереди, содержащей указатели на все узлы дерева в порядке их горизонтального обхода }
procedure PBDGP (var BegQ, EndQ: TPointQueue);
var EndQ, WPB, WPE: TPointQueue;
begin
WPB:= BegQ;
while WPB <> Nil do
begin
{элементы дописываются в очередь до тех пор, пока не будут перебраны все узлы дерева. У последнего элемента очереди в поле Next стоит Nil}
if WPB^.PNTree^.Left <> Nil then
InsertQ (BegQ, EndQ, WPB^. PNTree^.Left); {занесение левого потомка узла дерева в очередь.}
if WPB^.PNTree^.Right <> Nil then
InsertQ (BegQ, EndQ, WPB^. PNTree^.Right); {занесение правого потомка узла дерева в очередь.}
WPB := WPB^.Next;
end;
end;
Обращение к этим процедурам имеет вид:
begin
• • •
PBDPP (Rut);
• • •
PBDSP (Rut);
• • •
PBDOP (Rut);
• • •
BeginQueue := Nil;
EndQueue := Nil;
InsertQ (BeginQueue, EndQueue, Rut); {занесение корня дерева в очередь}
PBDGP (, BeginQueue, EndQueue);
• • •
end.
Для того чтобы показать универсальность приведенных процедур и подчеркнуть разницу между левым и правым поддеревом, рассмотрим два других пример дерева и результаты их обхода в прямом, симметричном и обратном порядке.
Пусть дано дерево:
A
B
C D
E F G H
I J K L
Для данного дерева получим следующие результаты обхода:
Прямой порядок: A B C E I F J D G H K L
Симметричный порядок: E I C F J B G D K H L A
Обратный порядок: I E J F C G K L H D B A
Горизонтальный порядок A B C D E F G H I J K L
Пусть дано дерево:
A
B M
C D
F G H
J K L
E
I
Для данного дерева получим следующие результаты обхода:
Прямой порядок: A B C F J E I D G M H K L
Симметричный порядок: C F I E J B G D A M K H L
Обратный порядок: I E J F C G D B K L H M A
Горизонтальный порядок A B M C D F G H J K L E I