Обсуждение участника:Novik — различия между версиями
Novik (обсуждение | вклад) (→Псевдокод) |
Novik (обсуждение | вклад) м (→Проверка двоичного дерева) |
||
Строка 1: | Строка 1: | ||
== Двоичное дерево поиска == | == Двоичное дерево поиска == | ||
− | ===Проверка двоичного дерева=== | + | ===Проверка двоичного дерева на инвариант дерева поиска=== |
Дано произвольное двоичное дерево и необходимо узнать является ли оно деревом поиска. Чтобы дерево было деревом поиска достаточно выполнение следующих условий для всех вершин: | Дано произвольное двоичное дерево и необходимо узнать является ли оно деревом поиска. Чтобы дерево было деревом поиска достаточно выполнение следующих условий для всех вершин: | ||
* правое и левое поддеревья являются деревьями поиска, | * правое и левое поддеревья являются деревьями поиска, |
Версия 21:51, 26 мая 2015
Содержание
Двоичное дерево поиска
Проверка двоичного дерева на инвариант дерева поиска
Дано произвольное двоичное дерево и необходимо узнать является ли оно деревом поиска. Чтобы дерево было деревом поиска достаточно выполнение следующих условий для всех вершин:
- правое и левое поддеревья являются деревьями поиска,
- максимум в левом поддереве меньше значения в текущей вершине, а минимум в правом больше.
Псевдокод
Для решения этой задачи нам понадобятся стандартные функции getMax и getMin, которые возвращают максимум и минимум в дереве поиска соответственно.
boolean isSearchTree(Node v): if (v.l == null && v.r == null) // Если текущая вершина - лист return true; if (isSearchTree(v.l) && isSearchTree(v.r) && getMax(v.l) < v.val && getMin(v.r) > v.val) // getMax и getMin запускаются только, если оба поддерева являются деревьями поиска return true; // Поддерево является деревом поиска else return false;
Поиск максимального целого поддерева, являющегося деревом поиска
Под размером дерева будем понимать количество вершин в нем. Тогда, чтобы получить решение модифицируем решение предыдущей задачи. Для каждой вершины так же будем хранить размер поддерева поиска, в котором она является корнем. Тогда получается, что для листьев он равен
, для всех остальных вершин надо проверить является ли их поддерево деревом поиска. Если да, то размер будет равен сумме размеров поддеревьев сыновей плюс один (т.к. учитываем текущую вершину), иначе .Псевдокод
Глобальная переменная ans хранит ссылку на корень текущего максимально поддерева поиска.
boolean isSearchTree(Node v): if (v.l == null && v.r == null) // Если текущая вершина - лист v.max = v.val; v.min = v.val; v.size = 1; if (1 > currMaxSize) ans = v; currMaxSize = 1; return true; if (isSearchTree(v.l) && isSearchTree(v.r) && v.l.max < v.val && v.r.min > v.val) v.max = v.r.max; v.min = v.l.min; v.size = v.l.size + v.r.size + 1; if (v.size > currMaxSize) ans = v; currMaxSize = v.size; return true; else v.size = 1; return false;
Поиск максимального поддерева, являющегося деревом поиска
В этой задаче нам не требуется найти целое дерево, то есть у любой в таком дереве вершины может не быть одного из поддеревьев. Тогда для решения проверку левого и правого поддеревьев надо сделать отдельно.
Псевдокод
boolean isSearchTree(Node v): v.max = v.val; v.min = v.val; boolean flag = false; // true - дерево является деревом поиска, false - нет - лист v.size = 1; if (v.l == null && v.r == null) // Если текущая вершина - лист if (1 > currMaxSize) ans = v; currMaxSize = 1; return true; if (isSearchTree(v.l) && v.l.max < v.val) v.min = v.l.min; v.size += v.l.size; flag = true; if (isSearchTree(v.r) && v.r.min > v.val) v.max = v.r.max; v.size += v.r.size; flag = true; if (flag && v.size > currMaxSize) ans = v; currMaxSize = v.size; if (flag) return true; else v.size = 1; return false;