AVL是平衡树,平衡因子概念什么的就不阐述了,主要是在不平衡时候如何旋转。(1)右子树右节点插入:左旋转。(2)左子树左节点插入:右旋转。(3)右子树左节点插入:右旋转后左旋转。(4)左子树右节点插入:左旋转后右旋转。深入了解可以参考:https://www.wulaoer.org/?p=1598
- 所谓的左旋和右旋都是以子树为原点的:如b是a的子树,那么旋转就围绕b来进行。
- 如果b是a的左子树,那么就围绕b将a向右旋转,看着就像是a直接掉下来了,掉成了b的右子树。
- 如果b是a的右子树,那么就围绕b将a向左旋转,看着就像是a直接掉下来了,掉成了b的左子树。
AVL树有左右孩子的概念,所以,在实现AVL树之前,有必要先引入Python中类的概念,先来个MWE。
Python的类
#!/usr/bin/python3 #coding:utf-8 #~~~~~~~~~~~~www.wulaoer.org 吴老二个人博客~~~~~~~ class Car: # 初始化 def __init__(self, brand, gas): self.brand = brand self.gas = gas print('一辆新的', self.brand, '被生产出来了!') # 定义方法 def add_gas(self, amount): self.gas += amount # 定义方法 def show_gas(self): print('剩余汽油:', self.gas) # 实例化 benz = Car('Benz', 100) # 调用方法 benz.add_gas(200) benz.show_gas()
AVL树的实现
#!/usr/bin/python3 #coding:utf-8 #~~~~~~~~~~~~www.wulaoer.org 吴老二个人博客~~~~~~~ import numpy as np import time class TreeNode(object): # 定义每个节点的数据,左孩子右孩子,平衡因子 def __init__(self): self.data = 0 self.left = None self.right = None self.height = 0 class BTree(object): def __init__(self): self.root = None def __Max(self, h1, h2): if h1 > h2: return h1 elif h1 <= h2: return h2 # 左左情况,向右旋转 def __LL(self, r): node = r.left r.left = node.right node.right = r r.height = self.__Max(self.getHeight(r.right), self.getHeight(r.left)) + 1 node.height = self.__Max(self.getHeight(node.right), self.getHeight(node.left)) + 1 return node # 右右,左旋 def __RR(self, r): node = r.right r.right = node.left node.left = r r.height = self.__Max(self.getHeight(r.right), self.getHeight(r.left)) + 1 node.height = self.__Max(self.getHeight(node.right), self.getHeight(node.left)) + 1 return node # 左右,先左旋再右旋 def __LR(self, r): r.left = self.__RR(r.left) return self.__LL(r) # 右左,先右旋再左旋 def __RL(self, r): r.right = self.__LL(r.right) return self.__RR(r) # r是self.root def __insert(self, data, r): if r == None: node = TreeNode() node.data = data return node elif data == r.data: return r elif data < r.data: r.left = self.__insert(data, r.left) # 左高右低 if self.getHeight(r.left) - self.getHeight(r.right) >= 2: if data < r.left.data: r = self.__LL(r) else: r = self.__LR(r) else: r.right = self.__insert(data, r.right) if self.getHeight(r.right) - self.getHeight(r.left) >= 2: if data > r.right.data: r = self.__RR(r) else: r = self.__RL(r) r.height = self.__Max(self.getHeight(r.left), self.getHeight(r.right)) + 1 return r # 删除data节点 def __delete(self, data, r): if r == None: return r elif r.data == data: # 如果只有右子树,直接将右子树赋值到此节点 if r.left == None: return r.right # 如果只有左子树,直接将左子树赋值到此节点 elif r.right == None: return r.left # 如果同时有左右子树 else: # 左子树高度大于右子树 if self.getHeight(r.left) > self.getHeight(r.right): # 找到最右节点 返回节点值 并删除该节点 node = r.left while(node.right != None): node = node.right r = self.__delete(node.data, r) r.data = node.data return r # 右子树高度大于左子树 else: node = r.right while node.left != None: node = node.left r = self.__delete(node.data, r) r.data = node.data return r elif data < r.data: # 在左子树中删除 r.left = self.__delete(data, r.left) # 右子树高度与左子树高度相差超过1 if self.getHeight(r.right) - self.getHeight(r.left) >= 2: if self.getHeight(r.right.left) > self.getHeight(r.right.right): r = self.__RL(r) else: r = self.__RR(r) elif data > r.data: # 右子树中删除 r.right = self.__delete(data, r.right) # 左子树与右子树高度相差超过1 if self.getHeight(r.left)-self.getHeight(r.right) >= 2: if self.getHeight(r.left.right)>self.getHeight(r.left.left): r = self.__LR(r) else: r = self.__LL(r) # 更新高度 r.height = self.__Max(self.getHeight(r.left), self.getHeight(r.right))+1 return r # 先序遍历 def __show(self, root): if root != None: # print (root.data) self.__show(root.left) self.__show(root.right) else: return 0 def Insert(self, data): self.root = self.__insert(data, self.root) return self.root def Delete(self, data): self.root = self.__delete(data, self.root) # 求结点的高度 def getHeight(self, node): if node == None: return -1 # print node return node.height def Show(self): self.__show(self.root) if __name__ == '__main__': bi = BTree() insert_time = [] delete_time = [] for right_interval in range(1000, 500000, 50000): array = np.random.randint(1, 100, right_interval) since = time.time() for i in array: bi.Insert(i) end = time.time() - since insert_time.append(end) print('AVL insert : ' + str(right_interval) + ' Data: ' + str(end) + 's') for right_interval in range(1000, 500000, 50000): array = np.random.randint(1, 100, right_interval) since = time.time() for i in array: bi.Delete(i) end = time.time() - since delete_time.append(end) print('AVL delete : ' + str(right_interval) + ' Data: ' + str(end) + 's') for i in array: bi.Insert(i)
运行结果
AVL insert : 1000 Data: 0.0071680545806884766s AVL insert : 51000 Data: 0.3300008773803711s AVL insert : 101000 Data: 0.6365611553192139s AVL insert : 151000 Data: 0.969146728515625s AVL insert : 201000 Data: 1.2616446018218994s AVL insert : 251000 Data: 1.572361946105957s AVL insert : 301000 Data: 1.8841772079467773s AVL insert : 351000 Data: 2.36479115486145s AVL insert : 401000 Data: 2.8726420402526855s AVL insert : 451000 Data: 3.1849629878997803s AVL delete : 1000 Data: 0.0023190975189208984s AVL delete : 51000 Data: 0.018627166748046875s AVL delete : 101000 Data: 0.037735939025878906s AVL delete : 151000 Data: 0.05629992485046387s AVL delete : 201000 Data: 0.06780004501342773s AVL delete : 251000 Data: 0.12815308570861816s AVL delete : 301000 Data: 0.1400139331817627s AVL delete : 351000 Data: 0.12156200408935547s AVL delete : 401000 Data: 0.1407301425933838s AVL delete : 451000 Data: 0.16689515113830566s Process finished with exit code 0
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏