AVL树插入(Python实现)
Posted ok代码我改了
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AVL树插入(Python实现)相关的知识,希望对你有一定的参考价值。
建立AVL树
1 class AVLNode(object): 2 def __init__(self,data): 3 self.data = data 4 self.lchild = None 5 self.rchild = None 6 self.parent = None 7 self.bf = 0 8 9 class AVLTree(object) 10 def __init__(self,li=None) 11 self.root = None 12 if li: 13 for val in li: 14 self.insert(self.root,val) 15 16 def insert(self,node,val): 17 if not node: 18 node = AVLNode(val) 19 elif val < node.data: 20 node.lchild = self.insert(node.lchild,val) 21 node.lchild.parent = node 22 elif val > node.data: 23 node.rchild = self.insert(node.rchild,val) 24 node.rchild.parent = node 25 return node
左旋转、右旋转
1 def rorate_left(self,p,c): 2 s2 = c.lchild 3 p.rchild = s2 4 if s2: 5 s2.parent = p 6 c.lchild = p 7 p.parent = c 8 p.bf = 0 9 c.bf = 0 10 return c 11 12 def rorate_right(self,p,c): 13 s2 = c.rchild 14 p.lchild = s2 15 if s2: 16 s2.parent 17 c.rchild = p 18 p.parent = c 19 p.bf = 0 20 c.bf = 0 21 return c
右→左旋转、左→右旋转
1 def rotate_right_left(self,p,c): 2 g = c.lchild 3 4 #右旋 5 s3 = g.rchild #1.把右孩子拿出来 6 c.lchild = s3 #2.右孩子交给 C 7 if s3: 8 s3.parent = c 9 g.rchild = c #3.链接右孩子 10 c.parent = g #4.链接父结点 11 12 #左旋 13 s2 = g.lchild 14 p.rchild = s2 15 if s2: 16 s2.parent = p 17 g.lchild = p 18 p.parent = g 19 20 #更新bf 21 if g.bf > 0: #插入到s3 #是指刚插入节点的g的平衡值 22 p.bf = -1 23 c.bf = 0 24 elif g.bf < 0: #插入到s2 25 p.bf = 0 26 c.bf = 1 27 else: #插入的是G本身 28 p.bf = 0 29 c.bf = 0 30 g.bf = 0 31 return g 32 33 def rotate_left_right(self,p,c): 34 g = c.rchild 35 36 #左旋 37 s2 = g.lchild 38 c.rchild = s2 39 if s2: 40 s2.parent = c 41 g.lchild = c 42 c.parent = g 43 44 #右旋 45 s3 = g.rchild 46 p.lchild = s3 47 if s3: 48 s3.parent = p 49 g.rchild = p 50 p.parent = g 51 52 #更新bf 53 if g.bf < 0: #插入到s2 54 p.bf = 1 55 c.bf = 0 56 elif g.bf > 0: #插入到s3 57 p.bf = 0 58 c.bf = -1 59 else: #插入的是G本身 60 p.bf = 0 61 c.bf = 0 62 g.bf = 0 63 return g
插入
1 def insert_no_rec(self,val): 2 #1.插入 3 p = self.root 4 if not p: 5 self.root = AVLNode(val) 6 return 7 while True: 8 if val < p.data: 9 if p.lchild: #左孩子存在 10 p = p.lchild 11 else: #左孩子不存在 12 p.lchild = AVLNode(val) 13 p.lchild.parent = p 14 node = p.lchild #node 存储的就是插入的节点 15 break 16 else val > p.data: 17 if p.rchild: 18 p = p.rchild 19 else: 20 p.rchild = AVLNode(val) 21 p.rchild.parent = p 22 node = p.rchild 23 break 24 else: #等于 #同样的元素不多次插入 25 #avl尽量不允许两个相同的数插入 26 return 27 28 #2.更新balance factor 29 while node.parent: #node.parent 不为空时 30 if node.parent.lchild == node: #传递节点是在左子树,左子树更沉了 31 #第一乱循环,更新node.parent的bf -= 1 32 if node.parent.bf < 0: #原来node.parent.bf == -1 (更新后会变成-2) 33 # 做旋转 34 # 看node哪边沉 35 head = node.parent.parent #为了链接旋转之后的子树 36 tmp = node.parent #旋转前的子树的根 37 if node.bf > 0: 38 n = self.rotate_left_right(node.parent,node) 39 else: 40 n = self.rorate_right(node.parent,node) 41 elif node.parent.bf > 0: #原来node.parent.bf == 1 (更新后变成0) 42 node.parent.bf = 0 #平衡,即可以不需要确认父亲节点 43 break 44 else: #原来node.parent.bf = 0,更新之后变成-1 45 node.parent.bf = -1 46 node = node.parent 47 continue 48 else: #传递节点是在右子树,右子树更沉了 49 if node.parent.bf > 0: 50 head = node.parent.parent 51 tmp = node.parent 52 if node.bf < 0: 53 n = self.rotate_right_left(node.parent,node) 54 else: 55 n = self.rorate_left(node.parent,node) 56 elif node.parent.bf < 0: 57 node.parent.bf = 0 58 break 59 else: 60 node.parent.bf = 1 61 node = node.parent 62 continue 63 64 #3.链接旋转后的子树(只有做了旋转之后才会到这一步) 65 n.parent = head 66 if head: #head不是空 67 if tmp == head.lchild: 68 head.lchild = n 69 else: 70 head.rchild = n 71 break 72 else: 73 self.root = n 74 break
以上是关于AVL树插入(Python实现)的主要内容,如果未能解决你的问题,请参考以下文章