- AVL树(平衡二叉树)
- 总结
方法 | 功能 |
---|---|
find(data) | 查找值为data的节点是否存在树中 |
height() | 返回当前树高 |
insert(data) | 插入值为data的节点 |
delete(data) | 删除值为data的节点 |
get_pre(root) | 返回root节点的前驱 |
inorder(root) | 中序遍历 |
#节点类。AVL树相对一般二叉搜索树,节点增加树高属性,便于判断是否平衡,从而决定是否进行调整等。
class Node:
def __init__(self, data = -1, height = 1, left = None, right = None):
self.data = data
self.left = left
self.right = right
self.height = height
def __str__(self):
return str(self.data)
class AVLTree:
def __init__(self, root=None):
self.root = root
# 增加一些公有私有机制
def find(self, data):
if self.root == None:
return None
return self.__find(self.root, data)
def __find(self, root, data):
if root == None:
return None
if root.data == data:
return root
elif root.data < data:
return self.__find(root.right, data)
else:
return self.__find(root.left, data)
def height(self):
if self.root == None:
return 0
return self.root.height
def __update(self, root):
root.height = 1
if root.left != None:
root.height = max(root.height, root.left.height + 1)
if root.right != None:
root.height = max(root.height, root.right.height + 1)
def __left_rotate(self, root):
tmp = root.right
root.right = tmp.left
tmp.left = root
self.__update(root)
self.__update(tmp)
return tmp
def __right_rotate(self, root):
tmp = root.left
root.left = tmp.right
tmp.right = root
self.__update(root)
self.__update(tmp)
return tmp
def get_pre(self, root):
tmp = root.left
while tmp.right != None:
tmp = tmp.right
return tmp
def insert(self, data):
self.root = self.__insert(self.root, data)
def __insert(self, root, data):
if root == None:
return Node(data)
if root.data == data:
return root
if root.data < data:
root.right = self.__insert(root.right, data)
else:
root.left = self.__insert(root.left, data)
self.__update(root)
return self.__maintain(root)
def delete(self, data):
self.root = self.__delete(self.root, data)
def __delete(self, root, data):
if root == None:
return root
if root.data < data:
root.right = self.__delete(root.right, data)
elif root.data > data:
root.left = self.__delete(root.left, data)
else:
if root.left == None or root.right == None:
tmp = root.left if root.left != None else root.right
del root
return tmp
tmp = self.get_pre(root)
root.data = tmp.data
root.left = self.__delete(root.left, tmp.data)
self.__update(root)
return self.__maintain(root)
def __maintain(self, root):
left_h = root.left.height if root.left != None else 0
right_h = root.right.height if root.right != None else 0
if abs(left_h - right_h) <= 1:
return root
if left_h > right_h:
lright_h = root.left.right.height if root.left.right != None else 0
lleft_h = root.left.left.height if root.left.left != None else 0
if lright_h > lleft_h:
root.left = self.__left_rotate(root.left)
root = self.__right_rotate(root)
else:
rleft_h = root.right.left.height if root.right.left != None else 0
rright_h = root.right.right.height if root.right.right != None else 0
if rleft_h > rright_h:
root.right = self.__right_rotate(root.right)
root = self.__left_rotate(root)
return root
def inorder(self, root):
if root is None:
return []
res = [root.data]
left_res = self.inorder(root.left)
right_res = self.inorder(root.right)
return left_res + res + right_res
测试代码:
t = AVLTree()
def printf():
res = t.inorder(t.root)
for i in res:
print("{0}:({1}, {2})".format(t.find(i), t.find(i).left, t.find(i).right))
print("root =", t.root, "h =", t.height())
print()
for i in range(1, 10):
t.insert(i)
printf()
总结
这里的写法有点臃肿,主要是对于不存在的节点None,取不到height属性。所以对此需要if
特判,取得默认None情况的height为0值。
然后就是平衡二叉树,基 *** 就是进行旋转,回溯过程中,哪个地方不平衡了就立即调整,其它都同正常的BST。
还有一点就是写法问题,这次是用了_+name的形式书写方法名,化作私有方法,简而言之就是进行了多一层的封装,对外接口更加方便。对比上一个BST,我将节点的增删改查等方法以静态方法
的形式,封装在Node类中,应该是各有优势吧。(不是
下一篇进攻红黑树,对问题一的写法会有一个优化。话说就是这脑瘫的写法,搞得我debug半个钟。(节点树高的维护出错了,原因是__update() 方法中没加赋值那条语句)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)