-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathavl.py
More file actions
110 lines (96 loc) · 3.15 KB
/
avl.py
File metadata and controls
110 lines (96 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/usr/bin/env python
import bst
def height(node):
if node is None:
return -1
else:
return node.height
def update_height(node):
node.height = max(height(node.left), height(node.right)) + 1
class AVL(bst.BST):
"""
AVL binary search tree implementation.
Supports insert, delete, find, find_min, next_larger each in O(lg n) time.
"""
def left_rotate(self, x):
y = x.right
y.parent = x.parent
if y.parent is None:
self.root = y
else:
if y.parent.left is x:
y.parent.left = y
elif y.parent.right is x:
y.parent.right = y
x.right = y.left
if x.right is not None:
x.right.parent = x
y.left = x
x.parent = y
update_height(x)
update_height(y)
def right_rotate(self, x):
y = x.left
y.parent = x.parent
if y.parent is None:
self.root = y
else:
if y.parent.left is x:
y.parent.left = y
elif y.parent.right is x:
y.parent.right = y
x.left = y.right
if x.left is not None:
x.left.parent = x
y.right = x
x.parent = y
update_height(x)
update_height(y)
def rebalance(self, node):
while node is not None:
update_height(node)
if height(node.left) >= 2 + height(node.right):
if height(node.left.left) >= height(node.left.right):
self.right_rotate(node)
else:
self.left_rotate(node.left)
self.right_rotate(node)
elif height(node.right) >= 2 + height(node.left):
if height(node.right.right) >= height(node.right.left):
self.left_rotate(node)
else:
self.right_rotate(node.right)
self.left_rotate(node)
node = node.parent
## find(k), find_min(), and next_larger(k) inherited from bst.BST
def insert(self, k):
"""Inserts a node with key k into the subtree rooted at this node.
This AVL version guarantees the balance property: h = O(lg n).
Args:
k: The key of the node to be inserted.
"""
node = super(AVL, self).insert(k)
self.rebalance(node)
def delete(self, k):
"""Deletes and returns a node with key k if it exists from the BST.
This AVL version guarantees the balance property: h = O(lg n).
Args:
k: The key of the node that we want to delete.
Returns:
The deleted node with key k.
"""
node = super(AVL, self).delete(k)
## node.parent is actually the old parent of the node,
## which is the first potentially out-of-balance node.
self.rebalance(node.parent)
def test(args=None):
bst.test(args, BSTtype=AVL)
if __name__ == '__main__':
test_tree = AVL()
test_tree.insert(5)
test_tree.insert(10)
test_tree.insert(7)
test_tree.insert(11)
test_tree.insert(15)
test_tree.insert(1)
print(test_tree)