Lecture 6: Balanced Binary Search Trees
AVL树
定义: AVL树是自平衡二叉查找树, 每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1.
平衡(Balance):平衡最坏的情况是每个节点高度差1.
AVL 插入:
1. insert as in simple BST
2. work your way up tree, restoring AVL property (and updating heights as you go).
步骤:
suppose x is lowest node violating AVL .
assume x is right-heavy (left case symmetric)
if x's right child is right-heavy or balanced: follow steps in Fig. 5
else: follow steps in Fig. 6
then continue up to x's grandparent, greatgrandparent . . .
Example:
AVL 排序:
代码
'''
Created on 20151223
@author: Administrator
'''
class BST(object):
'''
classdocs
'''
def __init__(self):
'''
Constructor
'''
self.root = None
def insert(self,t):
newNode = BSTnode(t)
if(self.root is None):
self.root = newNode
else:
node = self.root
while(True):
if(t < node.key):
if(node.left is None):
node.left = newNode
newNode.parent = node
break
node = node.left
else:
if(node.right is None):
node.right = newNode
newNode.parent = node
break
node = node.right
return newNode
def find(self,t):
node = self.root
while (node is not None):
if(t == node.key):
return node
elif(t < node.key):
node = node.left
else:
node = node.right
return None
def find_min(self):
node = self.root
while(node is not None):
if(node.left is None):
return node
else:
node = node.left
return None
def delete_min(self):
"""Delete the minimum key (and return the old node containing it)."""
if self.root is None:
return None, None
else:
# Walk to leftmost node.
node = self.root
while node.left is not None:
node = node.left
# Remove that node and promote its right subtree.
if node.parent is not None:
node.parent.left = node.right
else: # The root was smallest.
self.root = node.right
if node.right is not None:
node.right.parent = node.parent
parent = node.parent
node.disconnect()
return node, parent
def __str__(self):
if self.root is None: return '<empty tree>'
def recurse(node):
if node is None: return [], 0, 0
label = str(node.key)
left_lines, left_pos, left_width = recurse(node.left)
right_lines, right_pos, right_width = recurse(node.right)
middle = max(right_pos + left_width - left_pos + 1, len(label), 2)
pos = left_pos + middle // 2
width = left_pos + middle + right_width - right_pos
while len(left_lines) < len(right_lines):
left_lines.append(' ' * left_width)
while len(right_lines) < len(left_lines):
right_lines.append(' ' * right_width)
if (middle - len(label)) % 2 == 1 and node.parent is not None and \
node is node.parent.left and len(label) < middle:
label += '.'
label = label.center(middle, '.')
if label[0] == '.': label = ' ' + label[1:]
if label[-1] == '.': label = label[:-1] + ' '
lines = [' ' * left_pos + label + ' ' * (right_width - right_pos),
' ' * left_pos + '/' + ' ' * (middle-2) +
'\\' + ' ' * (right_width - right_pos)] + \
[left_line + ' ' * (width - left_width - right_width) +
right_line
for left_line, right_line in zip(left_lines, right_lines)]
return lines, pos, width
return '\n'.join(recurse(self.root) [0])
class BSTnode(object):
"""
Representation of a node in a binary search tree.
Has a left child, right child, and key value.
"""
def __init__(self,t):
self.key = t
self.disconnect()
def disconnect(self):
self.left = None
self.right = None
self.parent = None
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):
"""
AVL binary search tree implementation.
Supports insert, find, and delete-min operations in O(lg n) time.
"""
def left_rotate(self, x):
print("left_rotate")
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):
print("right_rotate")
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 insert(self, t):
"""Insert key t into this tree, modifying it in-place."""
node = BST.insert(self, t)
self.rebalance(node)
def rebalance(self, node):
print("rebalance")
while node is not None:
#print("node = " +str(node.key) +" height = ",node.height)
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
def delete_min(self):
node, parent = BST.delete_min(self)
self.rebalance(parent)
#raise NotImplemented('AVL.delete_min')
test1 = range(0, 100, 10)
test2 = [31, 41, 59, 26, 53, 58, 97, 93, 73]
test3 = "algorithms"
#import random
def test(args=None, BSTtype=AVL):
items = test2
tree = BSTtype()
print (tree)
for item in items:
tree.insert(item)
print("------------------------------------------")
print (tree)
tree.delete_min()
print("------------------------------------------")
print(tree)
if __name__ == '__main__': test()
来源:oschina
链接:https://my.oschina.net/u/106593/blog/596817