平衡二叉排序树

def update(root, key=None):#插入删除都要update。
    #计算高度
    if key == None and root.left == None and root.right == None:#删除高度可能为0
        root.height = 0
        return root #修改height后直接返回调整上一层
    else:
        root.height = 1 + max(get_height(root.left), get_height(root.right))
    # 获取平衡因子
    balance = get_balance(root)
    if None == key:#删除时还看左右树的平衡 
        # 右旋,左左大了,LL型:(aAb)B(c)->(a)A(bBc)
        if balance > 1 and get_balance(root.left) >= 0:
            return rotate_right(root)
        # 左旋,右右大了,RR型:(a)A(bBc)->(aAb)B(c)
        if balance < -1 and get_balance(root.right) <= 0:
            return rotate_left(root)
        # 左右双旋,左右大了,LR型,((a)B(bCc))A(d)
        if balance > 1 and get_balance(root.left) < 0:
            root.left = rotate_left(root.left)#RR:(aBb)C(c)...A(d)
            return rotate_right(root)#LL:(aBb)C(cAd)
        # 右左双旋,右左大了,RL型,(a)A((bCc)B(d))
        if balance < -1 and get_balance(root.right) > 0:
            root.right = rotate_right(root.right)#LL:(a)A...(b)C(cBd)
            return rotate_left(root)#RR:(aAb)C(cBd)
    else:#插入调整,跟left比就是插入左树情况
        # 右旋
        if balance > 1 and key < root.left.key:
            return rotate_right(root)
        # 左旋
        if balance < -1 and key > root.right.key:
            return rotate_left(root)
        # 左右双旋
        if balance > 1 and key > root.left.key:
            root.left = rotate_left(root.left)
            return rotate_right(root)
        # 右左双旋
        if balance < -1 and key < root.right.key:
            root.right = rotate_right(root.right)
            return rotate_left(root)
    return root

def insert(root, key):
    if root is None:
        return AVLNode(key)
    if key < root.key:
        root.left = insert(root.left, key)
    elif key > root.key:
        root.right = insert(root.right, key)
    # 插入调整平衡
    return update(root, key) 

def find_min(root):#右子树的最小结点(最左值)
    if None == root.left:
        return root
    else:
        return find_min(root.left)
    
def delete(root, key):
    if root is None:
        return root    
    if key < root.key:
        root.left = delete(root.left, key)#处理左支
    elif key > root.key:
        root.right = delete(root.right, key)
    else:
        #没有子结点,删除连接,返回None
        if root.left == None and root.right == None:
            return None
        # 只有一个子结点,直接用子结点连接根
        if root.left is None:
            return root.right
        elif root.right is None:
            return root.left
        # 结点有两个子结点,找到右子树的最小结点(最左值)作根值
        root.key = find_min(root.right).key
        # 删除右子树的最小结点
        root.right = delete(root.right, root.key)
    # 平衡,更新所有高度
    return update(root)

def get_height(node):#默认0
    if node is None:
        return 0
    return node.height

def get_balance(node):
    if node is None:
        return 0
    return get_height(node.left) - get_height(node.right)

def rotate_left(z):#RR型,右支的右升高了。(a)A(bBc)->(aAb)B(c)
    y = z.right
    T2 = y.left
    # 执行左旋
    y.left = z
    z.right = T2
    # 更新结点的高度
    z.height = 1 + max(get_height(z.left), get_height(z.right))
    y.height = 1 + max(get_height(y.left), get_height(y.right))
    return y

def rotate_right(y):#LL型,左支的左升高了。(aAb)B(c)->(a)A(bBc)
    x = y.left
    T2 = x.right
    # 执行右旋
    x.right = y
    y.left = T2
    # 更新结点的高度
    y.height = 1 + max(get_height(y.left), get_height(y.right))
    x.height = 1 + max(get_height(x.left), get_height(x.right))
    return x
    
#层次序列,广度优先周游
def breadth_fisrt_level_traversal(node):
    if node is None: return
    temp = []
    temp.append(node)
    while temp:
        q=temp.pop(0)#用队列先进先出
        print(f"({q.key}, {q.height})", end=" ")
        if q.left:temp.append(q.left)
        if q.right:temp.append(q.right)
class AVLNode:
    def __init__(self, key):
        self.key = key
        self.height = 0
        self.left = None
        self.right = None

中根遍历结果: (5, 0) (10, 1) (27, 3) (41, 1) (51, 0) (73, 2) (90, 0) (99, 1)
层次序列: (27, 3) (10, 1) (73, 2) (5, 0) (41, 1) (99, 1) (51, 0) (90, 0)
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值