АВЛ-дерево — различия между версиями
Sementry (обсуждение | вклад) м |
Sementry (обсуждение | вклад) м |
||
| Строка 5: | Строка 5: | ||
АВЛ-деревья названы по первым буквам фамилий их изобретателей, Г. М. Адельсона-Вельского и Е. М. Ландиса, которые впервые предложили использовать АВЛ-деревья в 1962 году. | АВЛ-деревья названы по первым буквам фамилий их изобретателей, Г. М. Адельсона-Вельского и Е. М. Ландиса, которые впервые предложили использовать АВЛ-деревья в 1962 году. | ||
| + | == Высота дерева == | ||
| + | Высоту поддерева с корнем <tex>x</tex> будем обозначать как <tex>h(x)</tex>, высоту поддерева <tex>T</tex> {{---}} как <tex>h(T)</tex> | ||
| + | |||
| + | Можно показать, что в AVL-дереве высоты <tex>h</tex> не менее, чем <tex>F_h = \Omega(\varphi^h)</tex> вершин, где <tex>F_h - h</tex>-ое число Фиббоначи, <tex>\varphi = \frac{ \sqrt{5}+1}{2}</tex>. Делая замену <tex>h = \log_\varphi{n}</tex>, получаем, что высота AVL-дерева из n вершин - <tex>O(\log{n})</tex>. | ||
== Балансировка == | == Балансировка == | ||
| − | |||
{{Определение|definition= | {{Определение|definition= | ||
'''Балансировкой вершины''' называется операция, которая в случае разницы высот левого и правого поддеревьев <tex>|h(L) - h(R)| = 2</tex>, изменяет связи предок-потомок в поддереве данной вершины так, чтобы восстановилось свойство дерева <tex>|h(L) - h(R)| \le 1</tex>, иначе ничего не меняет. | '''Балансировкой вершины''' называется операция, которая в случае разницы высот левого и правого поддеревьев <tex>|h(L) - h(R)| = 2</tex>, изменяет связи предок-потомок в поддереве данной вершины так, чтобы восстановилось свойство дерева <tex>|h(L) - h(R)| \le 1</tex>, иначе ничего не меняет. | ||
| Строка 33: | Строка 36: | ||
|<tex>h(b) - h(R) = 2</tex> и <tex>h(c) > h(L)</tex>. | |<tex>h(b) - h(R) = 2</tex> и <tex>h(c) > h(L)</tex>. | ||
|} | |} | ||
| − | В каждом случае | + | В каждом случае можно показать, что операция приводит к нужному результату и что полная высота уменьшается не более чем на 1 и не может увеличиться. |
| + | |||
| + | Все операции балансировки, очевидно, требуют <tex>O(1)</tex> операций. | ||
| − | == | + | == Добавление вершины == |
| − | + | Процесс включения вершины состоит из двух частей: | |
# Прохода по пути поиска, пока не убедимся, что ключа в дереве нет. | # Прохода по пути поиска, пока не убедимся, что ключа в дереве нет. | ||
| − | + | # "Отступления" назад по пути поиска, вплоть до корня и пересчета высот в каждой вершине на обратном пути. При необходимости осуществляется балансировка. | |
| − | # "Отступления" назад по пути поиска и | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | == | + | Так как в процессе добавления вершины мы рассматриваем не более, чем <tex> O(h) </tex> вершин дерева, и для каждой запускаем балансировку не более одного раза, то суммарное количество операций при включении новой вершины в дерево составляет <tex> O(\log{n}) </tex> операций. |
| + | |||
| + | == Удаление вершины == | ||
Для простоты опишем рекурсивный алгоритм удаления. | Для простоты опишем рекурсивный алгоритм удаления. | ||
Если вершина - лист, то удалим её и вызовем балансировку всех её предков в порядке от родителя к корню. | Если вершина - лист, то удалим её и вызовем балансировку всех её предков в порядке от родителя к корню. | ||
| − | Иначе найдём самую близкую по значению вершину | + | Иначе найдём самую близкую по значению вершину и переместим её на место удаляемой вершины, при этом вызвав процедуру её удаления. |
| − | |||
| − | |||
| − | + | В результате указанных действий процедура удаления вызывается не более 3 раз, так как у вершины, удаляемой по 2-му вызову, нет хотя бы одного из поддеревьев. На балансировку суммарно тратится, как и ранее, <tex> O(h) </tex> операций. Таким образом, требуемое количество действий {{---}} <tex> O(\log{n}) </tex>. | |
Версия 08:09, 21 марта 2011
| Определение: |
| АВЛ-дерево — двоичное дерево поиска, в котором поддерживается следующее свойство: для каждой его вершины высота её двух поддеревьев различается не более чем на 1. |
АВЛ-деревья названы по первым буквам фамилий их изобретателей, Г. М. Адельсона-Вельского и Е. М. Ландиса, которые впервые предложили использовать АВЛ-деревья в 1962 году.
Высота дерева
Высоту поддерева с корнем будем обозначать как , высоту поддерева — как
Можно показать, что в AVL-дереве высоты не менее, чем вершин, где -ое число Фиббоначи, . Делая замену , получаем, что высота AVL-дерева из n вершин - .
Балансировка
| Определение: |
| Балансировкой вершины называется операция, которая в случае разницы высот левого и правого поддеревьев , изменяет связи предок-потомок в поддереве данной вершины так, чтобы восстановилось свойство дерева , иначе ничего не меняет. |
Указанный результат получается вращениями поддерева данной вершины. Используются 4 типа вращений:
| Тип вращения | Иллюстрация | Когда используется |
|---|---|---|
| Малое левое вращение | |
и . |
| Большое левое вращение | |
и . |
| Малое правое вращение | |
и . |
| Большое правое вращение | |
и . |
В каждом случае можно показать, что операция приводит к нужному результату и что полная высота уменьшается не более чем на 1 и не может увеличиться.
Все операции балансировки, очевидно, требуют операций.
Добавление вершины
Процесс включения вершины состоит из двух частей:
- Прохода по пути поиска, пока не убедимся, что ключа в дереве нет.
- "Отступления" назад по пути поиска, вплоть до корня и пересчета высот в каждой вершине на обратном пути. При необходимости осуществляется балансировка.
Так как в процессе добавления вершины мы рассматриваем не более, чем вершин дерева, и для каждой запускаем балансировку не более одного раза, то суммарное количество операций при включении новой вершины в дерево составляет операций.
Удаление вершины
Для простоты опишем рекурсивный алгоритм удаления. Если вершина - лист, то удалим её и вызовем балансировку всех её предков в порядке от родителя к корню. Иначе найдём самую близкую по значению вершину и переместим её на место удаляемой вершины, при этом вызвав процедуру её удаления.
В результате указанных действий процедура удаления вызывается не более 3 раз, так как у вершины, удаляемой по 2-му вызову, нет хотя бы одного из поддеревьев. На балансировку суммарно тратится, как и ранее, операций. Таким образом, требуемое количество действий — .