1、AVL
树
AVL
树的名字来源于它的发明作者 G.M. Adelson-Velsky
和 E.M. Landis
。AVL
树是最先发明的自平衡二叉查找树(Self-Balancing Binary Search Tree
,简称平衡二叉树)。
定义:
它或者是一颗空树,或者具有以下性质的二叉查找树:它的左子树和右子树的深度之差(平衡因子)的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。
时间复杂度:
AVL
树的查找、插入、删除操作在平均和最坏的情况下都是O(logn)
,这得益于它时刻维护着二叉树的平衡。如果我们需要查找的集合本身没有顺序,在频繁查找的同时也经常的插入和删除,AVL
树是不错的选择。
相关操作:
AVL
树失衡分类:
如果在AVL
树中进行插入或删除节点后,可能导致AVL
树失去平衡。这种失去平衡的可以概括为4种姿态:LL
(左左),LR
(左右),RR
(右右)和RL
(右左)。它们都有各自的定义:
LL:LeftLeft
,也称为"左左"。插入或删除一个节点后,根节点的左子树的左子树还有非空子节点,导致"根的左子树的高度"比"根的右子树的高度"大2,导致AVL
树失去了平衡。LR:LeftRight
,也称为"左右"。插入或删除一个节点后,根节点的左子树的右子树还有非空子节点,导致"根的左子树的高度"比"根的右子树的高度"大2,导致AVL
树失去了平衡。RL:RightLeft
,称为"右左"。插入或删除一个节点后,根节点的右子树的左子树还有非空子节点,导致"根的右子树的高度"比"根的左子树的高度"大2,导致AVL
树失去了平衡。RR:RightRight
,称为"右右"。插入或删除一个节点后,根节点的右子树的右子树还有非空子节点,导致"根的右子树的高度"比"根的左子树的高度"大2,导致AVL
树失去了平衡。
AVL
树的 Python
实现:
# -*- coding: utf-8 -*-
"""
Description:avl-tree: an auto-balanced binary search tree
"""
import math
import random
class MyQueue(object):
def __init__(self):
self.data = []
self.head = 0
self.tail = 0
def is_empty(self):
return self.head == self.tail
def push(self, data):
self.data.append(data)
self.tail += 1
def pop(self):
ret = self.data[self.head]
self.head += 1
return ret
def count(self):
return self.tail - self.head
def print(self):
print(self.data)
print("*****************")
print(self.data[self.head: self.tail])
class AVLTreeNode(object):
def __init__(self, data):
self.data = data
self.left = None
self.right = None
self.height = 1
def get_data(self):
return self.data
def get_left(self):
return self.left
def get_right(self):
return self.right
def get_height(self):
return self.height
def set_data(self, data):
self.data = data
def set_left(self, node):
self.left = node
return
def set_right(self, node):
self.right = node
return
def set_height(self, height):
self.height = height
return
def get_height(node):
if node is None:
return 0
return node.get_height()
def my_max(a, b):
return a if a > b else b
def left_rotation(node):
r"""
A B
/ \ / \
B C Bl A
/ \ --> / / \
Bl Br UB Br C
/
UB
UB = unbalanced node
这里传入的参数 node 是指节点 A
"""
print("left rotation node: ", node.get_data())
# 进行节点旋转
ret = node.get_left()
node.set_left(ret.get_right())
ret.set_right(node)
# 重新计算 height
h1 = my_max(get_height(node.get_right()), get_height(node.get_left())) + 1
node.set_height(h1)
h2 = my_max(get_height(ret.get_right()), get_height(ret.get_left())) + 1
ret.set_height(h2)
return ret
def right_rotation(node):
"""
a mirror symmetry rotation of the left_rotation
"""
print("right rotation node: ", node.get_data())
# 进行节点旋转
ret = node.get_right()
node.set_right(ret.get_left())
ret.set_left(node)
# 重新计算 height
h1 = my_max(get_height(node.get_right()), get_height(node.get_left())) + 1
node.set_height(h1)
h2 = my_max(get_height(ret.get_right()), get_height(ret.get_left())) + 1
ret.set_height(h2)
return ret
def rl_rotation(node):
r"""
A A Br
/ \ / \ / \
B C RR Br C LR B A
/ \ --> / \ --> / / \
Bl Br B UB Bl UB C
\ /
UB Bl
RR = right_rotation LR = left_rotation
这里传入的参数 node 是节点 A
"""
node.set_left(right_rotation(node.get_left()))
return left_rotation(node)
def lr_rotation(node):
node.set_right(left_rotation(node.get_right()))
return right_rotation(node)
def insert_node(root, data):
if root is None:
return AVLTreeNode(data)
if data < root.get_data():
root.set_left(insert_node(root.get_left(), data))
# an unbalance detected
if get_height(root.get_left()) - get_height(root.get_right()) == 2:
# new node is the left child of the left child
if data < root.get_left().get_data():
root = left_rotation(root)
else: # new node is the right child of the left child
root = rl_rotation(root)
else:
root.set_right(insert_node(root.get_right(), data))
if get_height(root.get_right()) - get_height(root.get_left()) == 2:
if data < root.get_right().get_data():
root = lr_rotation(root)
else:
root = right_rotation(root)
h1 = my_max(get_height(root.get_right()), get_height(root.get_left())) + 1
root.set_height(h1)
return root
def get_right_most(root):
while root.get_right() is not None:
root = root.get_right()
return root.get_data()
def get_left_most(root):
while root.get_left() is not None:
root = root.get_left()
return root.get_data()
def del_node(root, data):
if root.get_data() == data:
if root.get_left() is not None and root.get_right() is not None:
temp = get_left_most(root.get_right())
root.set_data(temp)
root.set_right(del_node(root.get_right(), temp))
elif root.get_left() is not None:
root = root.get_left()
else:
root = root.get_right()
elif root.get_data() > data:
if root.get_left() is None:
print("no such data!")
return root
else:
root.set_left(del_node(root.get_left(), data))
elif root.get_data() < data:
if root.get_right() is None:
return root
else:
root.set_right(del_node(root.get_right(), data))
if root is None:
return root
if get_height(root.get_right()) - get_height(root.get_left()) == 2:
if get_height(root.get_right().get_right()) > get_height(root.get_right().get_left()):
root = right_rotation(root)
else:
root = lr_rotation(root)
elif get_height(root.get_right()) - get_height(root.get_left()) == -2:
if get_height(root.get_left().get_left()) > get_height(root.get_left().get_right()):
root = left_rotation(root)
else:
root = rl_rotation(root)
height = my_max(get_height(root.get_right()), get_height(root.get_left())) + 1
root.set_height(height)
return root
class AVLTree(object):
def __init__(self):
self.root = None
def get_height(self):
return get_height(self.root)
def insert(self, data):
print("insert data: ", str(data))
self.root = insert_node(self.root, data)
def del_node(self, data):
print("delete data: ", str(data))
if self.root is None:
print("tree is empty.")
return
self.root = del_node(self.root, data)
def traversale(self):
# a level traversale, gives a more intuituve look on the tree
q = MyQueue()
q.push(self.root)
layer = self.get_height()
if layer == 0:
return
cnt = 0
while not q.is_empty():
node = q.pop()
space = " " * int(math.pow(2, layer -1))
print(space, end="")
if node is None:
print("*", end="")
q.push(None)
q.push(None)
else:
print(node.get_data(), end="")
q.push(node.get_left())
q.push(node.get_right())
print(space, end="")
cnt = cnt + 1
for i in range(100):
if cnt == math.pow(2, i) - 1:
layer = layer - 1
if layer == 0:
return
print()
break
return
def test(self):
get_height(None)
print("***")
self.get_height()
if __name__ == "__main__":
t = AVLTree()
t.traversale()
l = list(range(10))
random.shuffle(l)
for i in l:
t.insert(i)
t.traversale()
random.shuffle(l)
for i in l:
t.del_node(i)
t.traversale()
来源:CSDN
作者:阿牧路泽
链接:https://blog.csdn.net/sinat_33924041/article/details/103733909