Изменения

Перейти к: навигация, поиск

Дерево поиска, наивная реализация

236 байт убрано, 16:27, 9 июня 2012
Нет описания правки
[[Файл:Binary_search_tree.svg.png|right|200px300px|thumb|Бинарное дерево поиска из 9 элементов]]'''Бинарное дерево поиска (англ. binary search tree, BST)''' - структура данных для работы с динамическими множествами.Бинарное дерево поиска обладает следующим свойством: если <tex>x</tex> - узел бинарного дерева с ключом <tex>k</tex>, то все узлы в левом поддереве должны иметь ключи, меньшие или равные <tex>k</tex>, а в правом поддереве большие <tex>k</tex> (или в левом — строго меньшие, а в правом большие или равные).
== Операции в бинарном дереве поиска ==
=== Обход дерева поиска ===
Для вывода всех ключей бинарного дерева поиска в отсортированном порядке используется простой алгоритм (англ. ''inorder tree traversal'').
Tree_inorderinorderTreeWalk(node Node x) if(x != null) Tree_inorderinorderTreeWalk(x.left); print(x.key); Tree_inorderinorderTreeWalk(x.right);
Данный алгоритм выполняет обход за время <tex>O(n)</tex>, поскольку процедура вызывается ровно два раза для каждого узла дерева. Корректность данного алгоритма следует из свойств бинарного дерева поиска.
=== Поиск элемента ===
[[Файл:Bst search.png|thumb|250px318px|Поиск элемента 4]]Для поиска элемента в бинарном дереве поиска можно воспользоваться следующей процедурой, которая принимает в качестве параметров корень дерева и искомый ключ. Для каждого узла функция сравнивает значение его ключа с искомым ключом. Если ключи одинаковы, то функция возвращает текущий узел, в противном случае функция вызывается рекурсивно для левого или правого поддерева. Узлы, которые посещает функция образуют нисходящий путь от корня, так что время ее работы <tex>O(h)</tex>, где <tex>h</tex> - высота дерева. Tree_searchtreeSearch(node Node x, key k) if (x == null or k == x.key) return x; if (k < x.key) return Tree_searchtreeSearch(x.left, k);
else
return Tree_searchtreeSearch(x.right, k);Приведенная выше функция принимает в качестве параметров корень дерева и искомый ключ. Для каждого узла функция сравнивает значение его ключа с искомым ключом. Если ключи одинаковы, то функция возвращает текущий узел, в противном случае функция вызывается рекурсивно для левого или правого поддерева. Узлы, которые посещает функция образуют нисходящий путь от корня, так что время ее работы <tex>O(h)</tex>, где <tex>h</tex> - высота дерева.
=== Поиск минимума и максимума ===
Чтобы найти минимальный элемент в бинарном дереве поиска, необходимо просто следовать указателям left от корня дерева, пока не встретится значение null. Если у вершины есть левое поддерево, то по свойству бинарного дерева поиска в нем хранятся все элементы с меньшим ключом. Если его нет, значит эта вершина и есть минимальная. Аналогично ищется и максимальный элемент. Для этого нужно следовать правым указателям.
Tree_mintreeMinimum(root Node x) while (x.left != null) x = x.left; return x;
Tree_maxtreeMaximum(root Node x) while (x.right != null) x = x.right; return x;
Данные функции принимают корень дерева, и возвращают минимальный(максимальный) элемент в дереве. Обе процедуры выполняются за время <tex>O(h)</tex>.
=== Поиск следующего и предыдущего элемента ===
Если у узла есть правое поддерево, то следующий за ним элемент будет минимальным элементом в этом поддереве. Если у него нет правого поддерева, то нужно следовать вверх, пока не встретим узел, который является левым дочерним узлом своего родителя. Поиск предыдущего выполнятся аналогично. Если у узла есть левое поддерево, то следующий за ним элемент будет максимальным элементом в этом поддереве. Если у него нет левого поддерева, то нужно следовать вверх, пока не встретим узел, который является правым дочерним узлом своего родителя. Tree_nexttreeNext(root Node x) if (x.right != null) return Tree_mintreeMinimum(x.right); y = x.parent; while(y != null and x == y.right) x = y; y = y.parent; return y;
Tree_prevtreePrev(root Node x) if (x.left != null) return Tree_maxtreeMaximum(x.left); y = x.parent; while(y != null and x == y.left) x = y; y = y.parent; return y;Если у узла есть правое поддерево, то следующий за ним элемент будет минимальным элементом в этом поддереве. Если у него нет правого поддерева, то нужно следовать вверх, пока не встретим узел, который является левым дочерним узлом своего родителя. Поиск предыдущего выполнятся аналогично. Если у узла есть левое поддерево, то следующий за ним элемент будет максимальным элементом в этом поддереве. Если у него нет левого поддерева, то нужно следовать вверх, пока не встретим узел, который является правым дочерним узлом своего родителя. Обе операции выполняются за время <tex>O(h)</tex>.
=== Вставка ===
Операция вставки работает аналогично поиску элемента, только при обнаружении нулевого указателя нужно подвесить на него вставляемый элемент. Приведем итеративную реализацию этого алгоритма.
Tree_inserttreeInsert(root Node x, root Node z) // корень дерева, вставляемый элемент root Node y = null; while (x != null) y = x; if(z.key > x.key) x = x.right;
else
x = x.left; z.parent = y; if(z.key > y.key) y.right = z;
else
y.left = z;
Время работы алгоритма <tex>O(h)</tex>.
=== Удаление ===
|-
|'''Удаление листа'''
| [[Файл:Bst_del1.png‎|250px]]
|-
|'''Удаление узла с одним дочерним узлом'''
| [[Файл:Bst_del2.png‎|250px]]
|-
|'''Удаление узла с двумя дочерними узлами'''
| [[Файл:Bst_del3.png‎|250px]]
|-
|'''Удаление корня'''
| [[Файл:Bst_del4.png‎|250px]]
|}
Tree_deletetreeDelete(root Node t, root Node z) // корень дерева, вставляемый удаляемый элемент root Node x, y; if(z.left == null or z.right == null) y = z;
else
y = Tree_nexttreeNext(z); if(y.left != null) x = y.left;
else
x = y.right; if(x != null) x.parent = y.parent; if(y.parent == null) t = x;
else
if(y == y.parent.left) y.parent.left = x;
else
y.parent.right = x; if(y != z) z.key = y.key; z.data = y.data; return y;
== Литература ==
355
правок

Навигация