Обсуждение участника: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;

Поиск максимального поддерева, являющегося целым деревом поиска

Под размером дерева будем понимать количество вершин в нем. Тогда, чтобы получить решение модифицируем решение предыдущей задачи. Для каждой вершины так же будем хранить размер поддерева поиска, в котором она является корнем. Тогда получается, что для листьев он равен [math] 1 [/math], для всех остальных вершин надо проверить является ли их поддерево деревом поиска. Если да, то размер будет равен сумме размеров поддеревьев сыновей плюс один (т.к. учитываем текущую вершину), иначе [math] 1 [/math].

Псевдокод

Глобальная переменная 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;