Обсуждение участника:Novik — различия между версиями
Novik (обсуждение | вклад) (Двоичное дерево поиска) |
Novik (обсуждение | вклад) |
||
Строка 1: | Строка 1: | ||
== Двоичное дерево поиска == | == Двоичное дерево поиска == | ||
− | + | ===Проверка двоичного дерева=== | |
− | ==Проверка двоичного дерева== | ||
Дано произвольное двоичное дерево и необходимо узнать является ли оно деревом поиска. Чтобы дерево было деревом поиска достаточно выполнение следующих условий для всех вершин: | Дано произвольное двоичное дерево и необходимо узнать является ли оно деревом поиска. Чтобы дерево было деревом поиска достаточно выполнение следующих условий для всех вершин: | ||
* правое и левое поддеревья являются деревьями поиска, | * правое и левое поддеревья являются деревьями поиска, | ||
* максимум в левом поддереве меньше значения в текущей вершине, а минимум в правом больше. | * максимум в левом поддереве меньше значения в текущей вершине, а минимум в правом больше. | ||
− | Псевдокод: | + | ====Псевдокод==== |
+ | Для удобства опишем класс '''Node'''(вершина). В поле '''max''' будем хранить максимальное значение в данном поддереве, в поле '''min''' минимальное значение, а поля '''l''' и '''r''' хранят ссылки на левого и правого сыновей соответственно. | ||
+ | |||
+ | <code> | ||
+ | '''boolean''' isSearchTree(Node v): | ||
+ | '''if''' (v.l == null && v.r == null) <font color = "green">// Если текущая вершина - лист</font> | ||
+ | v.max = v.val; | ||
+ | v.min = v.val; | ||
+ | '''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; | ||
+ | '''return''' true; | ||
+ | '''else''' | ||
+ | '''return''' false; | ||
+ | </code> | ||
+ | ===Поиск максимального поддерева, являющегося целым деревом поиска=== | ||
+ | Под размером дерева будем понимать количество вершин в нем. Тогда, чтобы получить решение модифицируем решение предыдущей задачи. Для каждой вершины так же будем хранить размер поддерева поиска, в котором она является корнем. Тогда получается, что для листьев он равен <tex dpi = 120> 1 </tex>, для всех остальных вершин надо проверить является ли их поддерево деревом поиска. Если да, то размер будет равен сумме размеров поддеревьев сыновей плюс один (т.к. учитываем текущую вершину), иначе <tex dpi = 120> 1 </tex>. | ||
+ | |||
+ | ====Псевдокод==== | ||
+ | Глобальная переменная '''ans''' хранит ссылку на корень текущего максимально поддерева поиска. | ||
<code> | <code> | ||
'''boolean''' isSearchTree(Node v): | '''boolean''' isSearchTree(Node v): | ||
− | if (v.l == null && v.r == null) | + | '''if''' (v.l == null && v.r == null) <font color = "green">// Если текущая вершина - лист</font> |
v.max = v.val; | v.max = v.val; | ||
v.min = v.val; | v.min = v.val; | ||
− | return true; | + | v.size = 1; |
− | if (isSearchTree(v.l) && isSearchTree(v.r) && v.l.max < v.val && v.r.min > v.val) | + | '''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.max = v.r.max; | ||
v.min = v.l.min; | v.min = v.l.min; | ||
− | return true; | + | v.size = v.l.size + v.r.size + 1; |
− | else | + | '''if''' (v.size > currMaxSize) |
− | return false; | + | ans = v; |
+ | currMaxSize = v.size; | ||
+ | '''return''' true; | ||
+ | '''else''' | ||
+ | v.size = 1; | ||
+ | '''return''' false; | ||
</code> | </code> | ||
− | |||
− |
Версия 20:28, 24 мая 2015
Содержание
Двоичное дерево поиска
Проверка двоичного дерева
Дано произвольное двоичное дерево и необходимо узнать является ли оно деревом поиска. Чтобы дерево было деревом поиска достаточно выполнение следующих условий для всех вершин:
- правое и левое поддеревья являются деревьями поиска,
- максимум в левом поддереве меньше значения в текущей вершине, а минимум в правом больше.
Псевдокод
Для удобства опишем класс Node(вершина). В поле max будем хранить максимальное значение в данном поддереве, в поле min минимальное значение, а поля l и r хранят ссылки на левого и правого сыновей соответственно.
boolean isSearchTree(Node v): if (v.l == null && v.r == null) // Если текущая вершина - лист v.max = v.val; v.min = v.val; 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; 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;