# 平衡二叉树（AVL）python实现

AVL树是一种特殊的二叉搜索树 (BST树)，数据极端情况下, 二叉搜索树会退化成为单链表，但是AVL树通过旋转操作规避了这个问题。

# AVL树不适于删除的情况
class AVLTreeNode(object):
def __init__(self, data):
self.data = data  # 数据
self.left: AVLTreeNode = None  # 左子树
self.right: AVLTreeNode = None  # 右子树
self.height = 1  # 树高度

def get_data(node: AVLTreeNode):
return node.data

def set_data(node: AVLTreeNode, data):
node.data = data

# 获得树形结构
def get_left_node(node: AVLTreeNode):
return node.left

def get_right_node(node: AVLTreeNode):
return node.right

def get_height(node: AVLTreeNode):
if node is None:
return 0
return node.height

def get_max_node(node: AVLTreeNode):
temp_node = node
if temp_node.right is not None:
return get_max_node(temp_node.right)
else:
return temp_node

def get_min_node(node: AVLTreeNode):
temp_node = node
if temp_node.left is not None:
return get_min_node(temp_node.left)
else:
return temp_node

def get_node(node: AVLTreeNode, data):
temp_node: AVLTreeNode = node
while temp_node:
if data < temp_node.data:
temp_node = temp_node.left
elif data > temp_node.data:
temp_node = temp_node.right
else:
return temp_node
return None

# 右旋：先记录待旋转节点的左节点，然后将左节点的right指向待旋转节点即可
def right_rotate(node: AVLTreeNode):
node.height = max(get_height(node.left), get_height(node.right)) + 1

def left_rotate(node: AVLTreeNode):
node.height = max(get_height(node.left), get_height(node.right)) + 1

# 先左旋，再右旋
def left_right_rotate(node: AVLTreeNode):
son_node = left_rotate(node.left)
node.left = son_node
return right_rotate(node)

def right_left_rotate(node: AVLTreeNode):
son_node = right_rotate(node.right)
node.right = son_node
return left_rotate(node)

# 左子树与右子树差距最大为1，否则及时调整
if get_height(node.right) - get_height(node.left) > 1:
if get_height(node.right.right) > get_height(node.right.left):
node = left_rotate(node)
else:
node = right_left_rotate(node)
elif get_height(node.left) - get_height(node.right) > 1:
if get_height(node.left.left) > get_height(node.left.right):
node = right_rotate(node)
else:
node = left_right_rotate(node)
else:
pass
return node

def insert_node(node: AVLTreeNode, data):
if node is None:
return AVLTreeNode(data)
if (node.data is not None) and (data < node.data):  # 向左插入
node.left = insert_node(node.left, data)
node.height = max(get_height(node.left), get_height(node.right)) + 1
elif (node.data is not None) and (data > node.data):  # 向右插入
node.right = insert_node(node.right, data)
node.height = max(get_height(node.left), get_height(node.right)) + 1
else:
print('Can not insert same value')
return node

def delete_node(node: AVLTreeNode, data):
if node is None:
return None
if (node is not None) and (data < node.data):  # 左侧查询
node.left = delete_node(node.left, data)
elif (node is not None) and (data > node.data):  # 右侧查询
node.right = delete_node(node.right, data)
else:  # 在这里删除
if (node.left is not None) and (node.right is not None):  # 左右节点都不为空
node.data = get_min_node(node.right).data
node.right = delete_node(node.right, node.data)
elif node.left is not None:  # 左节点不为空，右节点为空
node = node.left
else:  # 左节点为空，右节点未知
node = node.right
if node is not None:
node.height = max(get_height(node.left), get_height(node.right)) + 1
return node

def get_all(node: AVLTreeNode):
values = []

if node is not None:
values.append(node.data)
return values

def main():
root = AVLTreeNode(10)
number_list = (3, 2, 1, 4, 5, 6, 7, 15, 26, 17)
for number in number_list:
root = insert_node(root, number)
all_values = get_all(root)
del_note = delete_node(root, 3)
all_values = get_all(root)
pass

if __name__ == '__main__':
main()


02-10 69

06-19 5144

01-05 157

03-27 188

01-04 22

11-11 36

08-22 1万+

01-25 161

07-25 2332

09-01 3096

08-22 478

08-16 64

04-13 66

07-23 2303

05-21 402

07-12 154

03-17 774

08-18 1491

03-19 80万+

04-14 56万+

02-19 16万+

02-27 7万+

02-28 4万+

03-01 12万+

03-01 11万+

03-03 6077

03-04 12万+

03-05 9648

03-05 5万+

03-08 6万+

03-08 1万+

04-25 6万+

03-10 12万+

03-10 17万+

03-10 6280

03-12 10万+

03-13 10万+

03-16 9943

03-19 7万+

03-20 4918

03-23 1万+

03-24 3万+

03-25 2万+

03-25 8万+

03-27 1万+

03-29 20万+

03-29 9万+

03-30 14万+

05-21 2853

03-31 1万+

05-25 5119

03-23 1万+

04-02 3万+

05-06 2万+

04-05 1万+

04-06 6万+

04-09 1万+

04-09 7万+

04-09 4645

04-10 4186

04-11 2万+

04-15 5万+

04-18 1万+

04-18 3730

04-18 4万+

04-20 3万+

04-24 2万+

04-26 3387

04-24 3972

04-30 7177

05-16 4万+

05-08 3万+

05-10 1820

05-11 3万+

05-13 6700

05-19 5615

05-13 9695

05-14 3605

#### python实用的几个脚本程序（自己在用）

©️2019 CSDN 皮肤主题: 书香水墨 设计师: CSDN官方博客