Центр оптико-нейронных технологий
ФГУ ФНЦ НИИСИ РАН |
|||||||||||||||||||
|
Основные алгоритмы работы с деревьями, основанные на обходахПодсчет числа узлов в бинарном деревеЗадача: подсчитать число узлов в бинарном дереве. Алгоритм может быть основан на любом обходе. При этом при попадании в каждый узел счетчик числа узлов увеличивается на 1. Приведем пример рекурсивной процедуры подсчета, основанной на a-обходе. (Для сравнения рядом с процедурой копирования приведена процедура a-обхода): подсчет числа узлов в дереве
a-обход
Использование процедуры подсчета:
(Пройти алгоритм по шагам на примере дерева: Можно записать подобным же образом функцию для подсчета числа узлов, аргументом которой является указатель на корень исходного дерева, а в качестве результата возвращается число узлов в дереве:
Подсчет числа узлов на заданном уровнеЗадача: подсчитать число узлов в бинарном дереве на заданном уровне level. Алгоритм может быть основан на любом обходе. При рекурсивном вызове процедуры каждый раз номер текущего уровня увеличивается на 1, и если значение этого счетчика совпадает с level, то счетчик числа узлов увеличивается на 1.
Использование процедуры подсчета:
Этот же алгоритм можно реализовать в виде функции:
Использование функции подсчета:
Печать бинарного дерева на экранеЗадача: распечатать бинарное дерево на экране так, чтобы узлы, составляющие левое (правое) поддерево для данного узла, были распечатаны на экране ниже и левее (правее) данного узла. Алгоритм основан на b-обходе (ЛКП). При попадании в узел сначала рекурсивно печатаем его левое поддерево, затем сам узел, затем его правое поддерево. Положение узла по вертикали (которое зависит от его уровня) передается в качестве параметра процедуры и увеличивается при переходе к более глубокому уровню. (Для работы процедуры необходимо подключить модуль crt, из которого используется процедура gotoxy для помещения курсора в заданную позицию на экране и функция wherex для получения текущей позиции курсора по горизонтали).
Например, для распечатки дерева, на корень которого указывает root, начиная со строки 10, нужно вызвать процедуру:
Удаление бинарного дереваЗадача: удалить все узлы бинарного дерева. Алгоритм основан на g-обходе (ЛПК). При попадании в узел сначала рекурсивно удаляем его левое поддерево, затем правое поддерево, и только затем удаляем сам узел. (Для сравнения рядом с процедурой удаления приведена процедура g-обхода): удаление дерева
g-обход
(параметр процедуры удаления передается по ссылке для того, чтобы после удаления дерева фактический параметр - указатель на корень дерева - получил значение nil) Использование процедуры удаления:
Зеркальное отражение дереваЗадача: превратить бинарное дерево в его зеркальное отражение, не создавая и не удаляя узлов, а только изменяя связи между ними. То есть, например, превратить дерево: в дерево Алгоритм основан на a или g-обходе. В случае a-обхода при попадании в узел сначала меняем местами указатели на его левое и правое поддеревья, после чего обрабатываем поддеревья. В случае g-обхода при попадании в узел сначала обрабатываем его поддеревья, а затем меняем местами указатели на левое и правое поддеревья. (b-обход здесь не подходит, так как при его использовании будет обрабатываться для каждого узла только одно поддерево). Пример процедуры, зеркально отражающей дерево, основанной на a-обходe:
Обработка узлов в порядке a, b и g-обходов с помощью одной процедурыЕсли все узлы некоторого дерева нужно обработать в порядке a, b и g-обходов, то в некоторых случаях для этого достаточно одной процедуры следующего вида:
Ясно, что таким образом можно объединять только те обходы, у которых совпадает порядок обработки левого и правого поддерева. То есть, например, можно построить общую процедуру для КЛП и ЛКП обходов, но нельзя построить общую процедуру для КЛП и ПКЛ обходов. В качестве примера объединенной процедуры приведем процедуру, которая для заданного дерева печатает на экране в строке 1 его КЛП-обход, в строке 2 - ЛКП-обход, в строке 3 - ЛПК-обход и удаляет дерево:
Сравнение бинарных деревьевЗадача: даны два бинарных дерева. Написать функцию, возвращающую true, если они равны (то есть имеют одинаковую структуру и значения информационных полей узлов), и FALSE, если не равны. Алгоритм сравнения рекурсивный: два дерева равны, если корень одного дерева со-держит такое же значение, что и корень второго дерева, и при этом равны соответствующие поддеревья. Пустые деревья равны по определению.
Копирование бинарного дереваЗадача: по существующему дереву построить дерево-копию. Пусть root1 - указатель на корень существующего дерева; root2 до выполнения алго-ритма равен nil, после выполнения указывает корень дерева-копии. Алгоритм копирования основан на a-обходе (КЛП). При попадании в каждый из узлов при обходе исходного де-рева создается очередной узел дерева-копии. (Для сравнения рядом с процедурой копиро-вания приведена процедура a-обхода): копирование дерева
a-обход
Использование процедуры копирования:
(Пройти алгоритм по шагам на примере дерева: ) Можно записать подобным же образом функцию для копирования дерева, аргументом которой является указатель на корень исходного дерева, а в качестве результата возвраща-ется указатель на корень дерева копии:
Использование функции копирования:
Поиск предшественника/преемника заданного узла при заданном обходеЗадача: для узла, содержащего в информационном поле заданное значение, определить узел, предшествующий ему (предшественник) и следующий за ним (преемник) при заданном обходе. Алгоритм поиска следующий. Вводится дополнительный указатель pold (указатель на предшествующий текущему узел) с начальным значением nil. Выполняется заданный обход. При попадании в каждый узел p проверяем, не совпадает ли его информационное поле с заданным значением (пусть это значение хранится в переменной sym). Если p^.info = sym, то pold указывает на предшественника, а следующий после p узел в обходе - преемник. В любом случае выполняем pold := p и продолжаем обход. Например, для поиска предшественника/преемника при b-обходе может быть использована следующая процедура:
Пример поиска предшественника и преемника узла, содержащего в информационном поле символ 'F':
Литература
Copyright c2000-2002 Михаил Марковский |
||||||||||||||||||
© Центр оптико-нейронных технологий
Федеральное государственное учреждение Федеральный научный центр Научно-исследовательский институт системных исследований Российской академии наук All rights reserved. 2016 г. |