3: (avl tree) - mkurnosov.net · (binary search trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000...

51
Лекция 3: АВЛ-деревья (AVL tree) КурносовМихаил Георгиевич к.т .н. доцент Кафедры вычислительных систем Сибирский государственный университет телекоммуникаций и информатики http://www.mkurnosov.net

Upload: others

Post on 03-Feb-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Лекция 3:

АВЛ-деревья

(AVL tree)

Курносов Михаил Георгиевич

к.т.н. доцент Кафедры вычислительных систем

Сибирский государственный университет

телекоммуникаций и информатики

http://www.mkurnosov.net

Page 2: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Двоичные деревья поиска

22

Двоичное дерево поиска (Binary Search Tree, BST) – это

двоичное дерево, в котором:

1) каждый узел (node) имеет не более двух дочерних узлов

(child nodes)

2) каждый узел содержит ключ (key) и значение (value)

и для него выполняются следующие условия:

� ключи всех узлов левого поддерева меньше значения

ключа родительского узла

� ключи всех узлов правого поддерева больше значения

ключа родительского узла

Page 3: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Двоичные деревья поиска (Binary Search Trees)

3

60Волк

35Рысь

90Ягуар

8Лиса

15Барсук

180Тигр

200Лев

4000Слон

600Медведь

9 узлов, глубина (depth) = 3

Value:

Key:

Min Max

Page 4: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Двоичные деревья поиска (Binary Search Trees)

4

1

Value

2

Value

1. Операции имеют трудоемкость

пропорциональную высоте дерева

2. В среднем случае высота дерева O(log(n))

3. В худшем случае элементы добавляются

по возрастанию (убыванию) ключей –

дерево вырождается в список длины n

bstree_add(1, value)

bstree_add(2, value)

bstree_add(3, value)

bstree_add(4, value)

3

Value

4

Value

NULL

NULL

NULL

Page 5: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Двоичные деревья поиска (Binary Search Trees)

55

ОперацияСредний случай

(average case)

Худший случай

(worst case)

Add(key, value) O(logn) O(n)

Lookup(key) O(logn) O(n)

Remove(key) O(logn) O(n)

Min O(logn) O(n)

Max O(logn) O(n)

Page 6: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Сбалансированные деревья поиска

6

� Сбалансированное дерево поиска (self-balancing

binary search tree) – дерево поиска, в котором высота

поддеревьев любого узла различаются не более чем на

заданную константу k

� Виды сбалансированных деревьев поиска:

o АВЛ-деревья (AVL tree)

o Красно-черные деревья (Red-black tree)

o B-деревья (B-tree)

o Splay tree

o AA tree

o Treap

o Scapegoat tree

o …

Page 7: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

AVL-деревья

7

� АВЛ-дерево (AVL tree) – сбалансированное по высоте

двоичное дерево поиска, в котором у любой вершины

высота левого и правого поддеревьев различаются

не более чем на 1

h

h - 2

h - 1

� Авторы:

Адельсон-Вельский Г.М., Ландис Е.М. Один алгоритм

организации информации // Доклады АН СССР. – 1962.

Т. 146, № 2. – C. 263–266.

� GNU libavl

� libdict

� Python avllib

� avlmap

Page 8: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

AVL tree

88

ОперацияСредний случай

(average case)

Худший случай

(worst case)

Add(key, value) O(logn) O(logn)

Lookup(key) O(logn) O(logn)

Remove(key) O(logn) O(logn)

Min O(logn) O(logn)

Max O(logn) O(logn)

Сложность по памяти: O(n)

Page 9: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

AVL-деревья

9

� Основная идея

Если вставка или удаление элемента приводит

к нарушению сбалансированности дерева, то выполняется

его балансировка

� Коэффициент сбалансированности узла (balance factor)

– это разность высот его левого и правого поддеревьев

� В АВЛ-дереве коэффициент сбалансированности любого

узла принимает значения из множества {-1, 0, 1}

� Высота узла (height) – это длина наибольшего пути от

него до дочернего узла, являющего листом

� Высота листа равна 0

� Высота пустого поддерева (NULL) равна -1

Page 10: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Высота узла (Node height)

10

10Height 3

5 20

124 7

2 10

2

1

0 0

1 0

1

Высота пустого

поддерева (NULL)

равна -1

Page 11: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Коэффициент сбалансированности

11

10

1

5

0

20

1

12

0

4

1

7

-1

2

0

10

0

Key:

Balance:Balance(x) =

H(Left) – H(Right)

Высота

поддерева = 1

Balance(4) =

= 0 - (-1) = 1

Page 12: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Коэффициент сбалансированности

12

10

2

5

0

20

0

4

1

7

-1

2

0

10

0

Key:

Balance:Balance(x) =

H(Left) – H(Right)

Высота

поддерева = 1

Balance(4) =

= 0 - (-1) = 1

Не AVL-дерево

Page 13: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Балансировка дерева (Rebalancing)

13

� После добавления нового элемента необходимо обновить

коэффициенты сбалансированности родительских узлов

� Если любой родительский узел принял значение -2 или 2,

то необходимо выполнить балансировку поддерева путем

поворота (rotation)

� Типы поворотов:

o Одиночный правый поворот (R-rotation, single right rotation)

o Одиночный левый поворот (L-rotation, single left rotation)

o Двойной лево-правый поворот (LR-rotation, double left-right

rotation)

o Двойной право-левый поворот (RL-rotation, double right-left

rotation)

Page 14: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Правый поворот (R-rotation)

14

2

3

1

2

0

1

� В левое поддерево добавили

элемент 1

� Дерево не сбалансированно

H(Left)=1 > H(Right)=-1

� Необходимо увеличить

высоту правого поддерева

Left Left case

Page 15: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Правый поворот (R-rotation)

15

� Поворачиваем ребро,

связывающее корень и его

левый дочерний узел, вправо

2

3

1

2

0

1

Page 16: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Правый поворот (R-rotation)

16

� Поворачиваем ребро,

связывающее корень и его

левый дочерний узел, вправо

2

3

1

2

0

1

0

2

0

1

0

3

Дерево

сбалансированно

Page 17: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Правый поворот (R-rotation)

17

P

L

T1 T2

T3

X

Правый поворот

в общем случае

L

P

T2 T3X

T1� В левое поддерево

вставлен элемент Х

� Дерево не сбалансированно

H(Left) > H(Right)

Page 18: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Правый поворот (R-rotation)

18

P

L

T1 T2

T3

X

Правый поворот

в общем случае

P.left = L.right

L.right = P

P.height = max(P.left.height,

P.right.height) + 1

L.height = max(L.left.height,

P.height) + 1

Page 19: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Левый поворот (L-rotation)

19

� В правое поддерево

вставлен элемент 3

� Поворачиваем ребро,

связывающее корень и его

правый дочерний узел, влево

-2

1-1

20

3

0

2

0

1

0

3

Дерево

сбалансированно

Right Right case

Page 20: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Левый поворот (L-rotation)

20

-2

P-1

R0

X

P.right = R.left

R.left = P

P.height = max(P.left.height, P.right.height) + 1

R.height = max(R.right.height, P.height) + 1

� В правое поддерево

вставлен элемент 3

� Поворачиваем ребро,

связывающее корень и его

правый дочерний узел, влево

Page 21: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Двойной лево-правый поворот (LR-rotation)

21

� LR-поворот выполняется после добавления элемента

в правое поддерево левого дочернего узла дерева

L

T1

R

T2 T3

X Xили

P

T4

1. L-поворот

левого поддерева P

2. R-поворот

нового дерева

с вершиной P

Left Right case

Page 22: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Двойной лево-правый поворот (LR-rotation)

22

� LR-поворот выполняется после добавления элемента

в правое поддерево левого дочернего узла дерева

L

T1

R

T2 T3

X Xили

P

T4

1. L-поворот

левого поддерева P

P.left = L_rotate(P.left)

Page 23: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Двойной лево-правый поворот (LR-rotation)

23

� LR-поворот выполняется после добавления элемента

в правое поддерево левого дочернего узла дерева

R

T3

L

T1 T2X

X

P

T4

1. L-поворот

левого поддерева P

Page 24: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Двойной лево-правый поворот (LR-rotation)

24

� LR-поворот выполняется после добавления элемента

в правое поддерево левого дочернего узла дерева

R

T3

L

T1 T2X

X

P

T4

2. R-поворот

нового дерева

c корнем P

P = R_rotate(P)

Page 25: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Двойной лево-правый поворот (LR-rotation)

25

� LR-поворот выполняется после добавления элемента

в правое поддерево левого дочернего узла дерева

R

T3

X

T1 T2

X

PL

T4

2. R-поворот

нового дерева

c корнем P

Page 26: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Двойной лево-правый поворот (LR-rotation)

26

� LR-поворот выполняется после добавления элемента

в правое поддерево левого дочернего узла дерева

2

3

-1

1

0

2

2

3

1

2

0

1

L-поворот

0

2

0

3

0

1

R-поворот

Page 27: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Двойной право-левый поворот (RL-rotation)

27

� RL-поворот выполняется после добавления элемента

в левое поддерево правого дочернего узла дерева

-2

1

1

3

0

2

L-поворот -1

2

0

3

-2

1

R-поворот

0

2

0

3

0

1

Right Left case

P.right = R_rotate(P.right)

P = L_rotate(P)

Page 28: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Повороты в АВЛ-дереве

28

� Любой поворот выполняется за константное время –

вычислительная сложность O(1)

� Любой поворот сохраняет свойства бинарного дерева

поиска (распределение ключей по левыми правым

поддеревьям)

Page 29: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Анализ эффективности АВЛ-деревьев

29

� Оценим сверху высоту АВЛ-дерева, содержащего n

элементов

� Обозначим через N(h) минимальное количество узлов

необходимых для формирования АВЛ-дерева высоты h

N(-1) = 0, N(0) = 1, N(1) = 2, N(2) = 4, N(3) = 7, …

0, 1, 2, 4, 7, 12, 20, 33, 54, …

h = 0 h = 1 h = 2 h = 3

Page 30: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Анализ эффективности АВЛ-деревьев

30

N(h) = N(h – 1) + N(h – 2) + 1

� N(h): 1, 2, 4, 7, 12, 20, 33, 54, …

� Fibonacci(h): 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, …

N(h) = F(h + 3) – 1, для h ≥ 0

Из формулы Бине для h-го члена последовательности Фибоначчи

– золотое сечение

Page 31: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Анализ эффективности АВЛ-деревьев

31

� Оценка сверху высоты h(n) АВЛ-дерева [Wirth89]:

log(n + 1) ≤ h(n) ≤ 1.4404·log(n + 2) – 0.328

� Оценка сверху высоты h(n) АВЛ-дерева[Levitin2006]:

log� � ≤ ℎ � ≤ 1.4405 log� � + 2 − 1.3277

Page 32: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

AVL Tree

32

struct avltree {

int key;

char *value;

int height;

struct avltree *left;

struct avltree *right;

};

Page 33: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

int main()

{

struct avltree *tree = NULL;

tree = avltree_add(tree, 10, "10");

tree = avltree_add(tree, 5, "5");

tree = avltree_add(tree, 3, "3");

tree = avltree_add(tree, 11, "11");

tree = avltree_add(tree, 12, "12");

avltree_print(tree);

avltree_free(tree);

return 0;

}

Построение AVL-дерева

33

11

5

3

10 12

Page 34: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

int main()

{

struct avltree *tree = NULL;

tree = avltree_add(tree, 5, "5");

tree = avltree_add(tree, 3, "3");

/* Code */

tree = avltree_delete(tree, 5);

avltree_free(tree);

return 0;

}

Удаление узлов из AVL-дерева

34

Page 35: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

void avltree_free(struct avltree *tree)

{

if (tree == NULL)

return;

avltree_free(tree->left);

avltree_free(tree->right);

free(tree);

}

Удаление всех узлов из AVL-дерева

35

11

5

3

10 12

Page 36: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

struct avltree *avltree_lookup(

struct avltree *tree, int key)

{

while (tree != NULL) {

if (key == tree->key) {

return tree;

} else if (key < tree->key) {

tree = tree->left;

} else {

tree = tree->right;

}

}

return tree;

}

Поиск узла по ключу

36

Page 37: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

struct avltree *avltree_create(int key,

char *value)

{

struct avltree *node;

node = malloc(sizeof(*node));

if (node != NULL) {

node->key = key;

node->value = value;

node->left = NULL;

node->right = NULL;

node->height = 0;

}

return node;

}

Создание узла

37

Page 38: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

int avltree_height(struct avltree *tree)

{

return (tree != NULL) ? tree->height : -1;

}

int avltree_balance(struct avltree *tree)

{

return avltree_height(tree->left) –

avltree_height(tree->right);

}

Высота и баланс узла (поддерева)

38

Page 39: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

struct avltree *avltree_add(

struct avltree *tree, int key, char *value)

{

if (tree == NULL) {

/* Insert new item */

return avltree_create(key, value);

}

Добавление узла

39

Page 40: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

if (key < tree->key) {

/* Insert into left subtree */

tree->left = avltree_add(tree->left,

key, value);

if (avltree_height(tree->left) –

avltree_height(tree->right) == 2)

{

/* Subtree is unbalanced */

if (key < tree->left->key) {

/* Left left case */

tree = avltree_right_rotate(tree);

} else {

/* Left right case */

tree = avltree_leftright_rotate(tree);

}

}

}

Добавление узла (продолжение)

40

Page 41: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

else if (key > tree->key) {

/* Insert into right subtree */

tree->right = avltree_add(tree->right,

key, value);

if (avltree_height(tree->right) -

avltree_height(tree->left) == 2)

{

/* Subtree is unbalanced */

if (key > tree->right->key) {

/* Right right case */

tree = avltree_left_rotate(tree);

} else {

/* Right left case */

tree = avltree_rightleft_rotate(tree);

}

}

}

Добавление узла (продолжение)

41

Page 42: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

tree->height = imax2(

avltree_height(tree->left),

avltree_height(tree->right)

) + 1;

return tree;

}

Добавление узла (конец)

42

Page 43: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

struct avltree *avltree_right_rotate(

struct avltree *tree)

{

struct avltree *left;

left = tree->left;

tree->left = left->right;

left->right = tree;

tree->height = imax2(

avltree_height(tree->left),

avltree_height(tree->right)) + 1;

left->height = imax2(

avltree_height(left->left),

tree->height) + 1;

return left;

}

R-поворот (left left case)

43

T

L

X

Page 44: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

struct avltree *avltree_left_rotate(

struct avltree *tree)

{

struct avltree *right;

right = tree->right;

tree->right = right->left;

right->left = tree;

tree->height = imax2(

avltree_height(tree->left),

avltree_height(tree->right)) + 1;

right->height = imax2(

avltree_height(right->right),

tree->height) + 1;

return right;

}

L-поворот (right right case)

44

T

R

X

Page 45: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

struct avltree *avltree_leftright_rotate(

struct avltree *tree)

{

tree->left = avltree_left_rotate(tree->left);

return avltree_right_rotate(tree);

}

LR-поворот (left right case)

45

Page 46: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

struct avltree *avltree_rightleft_rotate(

struct avltree *tree)

{

tree->right = avltree_right_rotate(tree->right);

return avltree_left_rotate(tree);

}

RL-поворот (right left case)

46

Page 47: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

void avltree_print_dfs(struct avltree *tree, int level)

{

int i;

if (tree == NULL)

return;

for (i = 0; i < level; i++)

printf(" ");

printf("%d\n", tree->key);

avltree_print_dfs(tree->left, level + 1);

avltree_print_dfs(tree->right, level + 1);

}

Вывод дерева на экран

47

Page 48: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

tree = avltree_add(tree, 10, "10");

tree = avltree_add(tree, 5, "5");

tree = avltree_add(tree, 3, "3");

tree = avltree_add(tree, 11, "11");

tree = avltree_add(tree, 12, "12");

avltree_print_dfs(tree, 0);

Вывод дерева на экран

48

5

3

11

10

12

11

5

3

10 12

Page 49: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

� Удаление элемента выполняется аналогично добавлению

� После удаления может нарушиться баланс нескольких

родительских вершин

� После удаления вершины может потребоваться

порядка O(logn) поворотов поддеревьев

Удаление элемента

49

Page 50: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

� С каждым узлом АВЛ-дерева ассоциирован флаг deleted

� При удалении узла находим его в дереве и устанавливаем

флаг deleted = 1 (реализуется за время O(logn))

� При вставке нового узла с таким же ключом как

и у удалённого элемента, устанавливаем у последнего

флаг deleted = 0 (в поле данных копируем новое значение)

� При достижении порогового значения количества узлов

с флагом deleted = 1 создаем новое АВЛ-дерево

содержащее все не удалённые узлы (deleted = 0)

� Поиск не удалённых элементов и их вставка в новое

АВЛ-дерево реализуется за время O(nlogn)

Ленивое удаление элементов (Lazy Deletion)

50

Page 51: 3: (AVL tree) - mkurnosov.net · (Binary Search Trees) 3 60 35"˙ 90 # 8 15 $ 180 % 200 4000 ˛ 600 9 & , ˚ (depth) = 3 Value: Key: Min Max ˘ ˙ !

Литература

51

1. Левитин А.В. Алгоритмы: введение в разработку и

анализ. – М.: Вильямс, 2006. – 576 с. (С. 267-271)

2. Вирт Н. Алгоритмы и структуры данных. – М.: Мир,

1989. – 360 с. (С. 272-286)

3. AVL-деревья // Сайт RSDN.ru. –

URL: http://www.rsdn.ru/article/alg/bintree/avl.xml

4. To Google:

“avl tree” || “avl tree ext:pdf” ||

“avl tree ext:ppt”