- •1. Графы: определения и примеры Неориентированные графы
- •Ориентированные графы
- •Взвешенные графы
- •2. Способы представления графов
- •Матрица смежности
- •Список ребер
- •Списки смежности
- •3. Деревья
- •Основные определения
- •4. Способы представления деревьев
- •5. Дерево двоичного поиска
- •7. Обходы графа
- •7.1 Процедура поиска в ширину
- •7.2 Процедура поиска в глубину
4. Способы представления деревьев
Поскольку любое дерево является графом, то его можно задавать любым из способов, перечисленных в п. "Способы представления графов". Однако существуют и специальные способы представления, предназначенные только для деревьев. Мы рассмотрим только два наиболее распространенных частных случая.
5. Дерево двоичного поиска
Дерево двоичного поиска для множества чисел S - это размеченное бинарное дерево, каждой вершине которого сопоставлено число из множества S, причем все пометки удовлетворяют следующим условиям:
существует ровно одна вершина, помеченная любым числом из множества S;
все пометки левого поддерева строго меньше, чем пометка текущей вершины;
все пометки правого поддерева строго больше, чем пометка текущей вершины.
Если выражаться простым языком, то структура дерева двоичного поиска подчиняется простому правилу: "если больше - направо, если меньше - налево".
Например, для набора чисел 7, 3, 5, 2, 8, 1, 6, 10, 9, 4, 11 получится такое дерево (см. рис. 14).
Для того чтобы правильно учесть повторения чисел, можно ввести дополнительное поле, которое будет хранить количество вхождений для каждого числа.
Более подробно процессы построения и анализа дерева бинарного поиска будут изложены в следующей лекции, посвященной алгоритмам, использующим деревья и графы.
Рис. 14. Дерево двоичного поиска
6. Обходы деревьев и графов
Прежде чем приступить к изложению алгоритмов обхода, дадим пару необходимых определений.
Обход дерева - это некоторая последовательность посещения всех его вершин.
Обход графа - это обход некоторого его каркаса.
Итак, приступим теперь к изучению различных вариантов обхода деревьев и графов.
Прямой обход
Другие названия
Префиксный обход: результатом прямого обхода дерева синтаксического анализа арифметического выражения будет префиксный вариант записи этого выражения.
Обход в глубину "сверху вниз": название имеет смысл лишь в случае стандартного расположения дерева корнем кверху.
Алгоритм PreOrder
Начать с корня дерева.
Пометить текущую вершину.
Совершить прямой обход левого поддерева.
Совершить прямой обход правого поддерева.
Обратный обход
Обход в глубину "снизу вверх": название имеет смысл лишь в случае стандартного расположения дерева корнем кверху.
Алгоритм PostOrder
Начать с корня дерева.
Совершить обратный обход левого поддерева.
Совершить обратный обход правого поддерева.
Пометить текущую вершину.
Обход в ширину
Последовательность обхода
Пометить вершину 0-го уровня (корень дерева).
Пометить все вершины 1-го уровня.
Пометить все вершины 2-го уровня.
...
Рис. 12.4. Последовательность нумерации вершин при синтаксическом обходе дерева
Алгоритм WideOrder
Занести в очередь корень дерева.
Пока очередь не станет пустой, повторять следующие действия:
удалить первый элемент из головы очереди;
добавить в хвост очереди всех потомков удаленной вершины.
Древесная сортировка
Задача. Упорядочить заданный набор (возможно, с повторениями) некоторых элементов (чисел, слов, т.п.).
Алгоритм TreeSort
Для сортируемого множества элементов построить дерево двоичного поиска:
первый элемент занести в корень дерева;
для всех остальных элементов: начать проверку с корня; двигаться влево или вправо (в зависимости от результата сравнения с текущей вершиной дерева) до тех пор, пока не встретится такой же элемент, либо пока не встретится nil. Во втором случае нужно создать новый лист в дереве, куда и будет записано значение нового элемента.
Совершить синтаксический обход построенного дерева, печатая каждую встреченную вершину столько раз, сколько было ее вхождений в сортируемый набор.
