• 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
    View Code

    左旋转、右旋转

     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
    View Code

    右→左旋转、左→右旋转

     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
    View Code

    插入

     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
    View Code
  • 相关阅读:
    Oracle DBA手记3:数据库性能优化与内部原理解析
    产品部和业务部门的利益之争
    利用dir函数查询各个数据类型的方法
    Python自动单元测试框架
    十一长假归来
    我心爱的TT被我擦到了,伤心!
    150首现代最流行的歌曲连放
    Increase bugzilla attachment size
    Python中的搜索路径
    抛出异常
  • 原文地址:https://www.cnblogs.com/steven2020/p/10687170.html
Copyright © 2020-2023  润新知