Python实现AVL树(平衡二叉搜索树)详解

介绍

AVL树,又称平衡二叉搜索树,是一种自平衡二叉搜索树,其每个节点的左右子树高度差(平衡因子)不超过1。当在AVL树中进行插入或删除操作后,系统会通过旋转操作来保持树的平衡性。在本文中,我们将详细介绍AVL树的实现,并包含左旋、右旋、左右旋、右左旋等平衡操作。

实现

首先,我们继承了二叉搜索树类 BST,并创建了AVL树的节点类 AVLNode。每个AVL节点除了包含数据、左孩子、右孩子和父节点外,还有一个平衡因子 bf,用于记录左右子树的高度差。

from Binary_search_tree import BiTreeNode, BST

class AVLNode(BiTreeNode):
    def __init__(self, data):
        BiTreeNode.__init__(self, data)
        self.bf = 0  # 平衡因子,右子树为正,左子树为负

接下来,我们实现了AVL树类 AVLTree,继承自BST类。在AVL树中,我们新增了四种旋转操作,包括左旋、右旋、左右旋和右左旋。这些旋转操作用于保持AVL树的平衡。

class AVLTree(BST):
    def __init__(self, li=None):
        BST.__init__(self, li)

    # 左旋
    def rotate_left(self, p, c):
        s2 = c.lchild
        p.rchild = s2
        if s2:
            s2.parent = p
        c.lchild = p
        p.parent = c

        p.bf = 0
        c.bf = 0
        return c

    # 右旋
    def rotate_right(self, p, c):
        s2 = c.rchild
        p.lchild = s2
        if s2:
            s2.parent = p
        c.rchild = p
        p.parent = c

        p.bf = 0
        c.bf = 0
        return c

    # 右旋-左旋
    def rotate_right_left(self, p, c):
        g = c.lchild
        self.rotate_right(p, c)
        self.rotate_left(g, c)
        if g.bf > 0:
            p.bf = -1
            c.bf = 0
        elif g.bf < 0:
            p.bf = 0
            c.bf = 1
        else:
            p.bf = 0
            c.bf = 0
        return g

    # 左旋-右旋
    def rotate_left_right(self, p, c):
        g = c.rchild
        self.rotate_left(c, g)
        self.rotate_right(p, c)
        if g.bf < 0:
            p.bf = 1
            c.bf = 0
        elif g.bf > 0:
            p.bf = 0
            c.bf = -1
        else:
            p.bf = 0
            c.bf = 0
        return g

    def insert_no_rec(self, val):
        p = self.root
        if not p:
            self.root = AVLNode(val)
            return
        while True:
            if val < p.data:
                if p.lchild:
                    p = p.lchild
                else:
                    p.lchild = AVLNode(val)
                    p.lchild.parent = p
                    node = p.lchild
                    break
            elif val > p.data:
                if p.rchild:
                    p = p.rchild
                else:
                    p.rchild = AVLNode(val)
                    p.rchild.parent = p
                    node = p.rchild
                    break
            else:
                return

        while node.parent:
            if node.parent.lchild == node:
                if node.parent.bf < 0:
                    g = node.parent.parent
                    x = node.parent
                    if node.bf > 0:
                        n = self.rotate_left_right(node.parent, node)
                    else:
                        n = self.rotate_right(node.parent, node)
                elif node.parent.bf > 0:
                    node.parent.bf = 0
                    break
                else:
                    node.parent.bf = -1
                    node = node.parent
                    continue
            else:
                if node.parent.bf > 0:
                    g = node.parent.parent
                    x = node.parent
                    if node.bf < 0:
                        n = self.rotate_right_left(node.parent, node)
                    else:
                        n = self.rotate_left(node.parent, node)
                elif node.parent.bf < 0:
                    node.parent.bf = 0
                    break
                else:
                    node.parent.bf = 1
                    node = node.parent
                    continue

            n.parent = g
            if g:
                if x == g.lchild:
                    g.lchild = n
                else:
                    g.rchild = n
                break
            else:
                self.root = n
                break

测试

最后,我们对实现的AVL树进行了简单的测试。首先,创建了一个包含0到100(步长为2)的AVL树,然后进行了插入操作。最后,输出了树的中序遍历结果,验证了AVL树的平衡性。

# 测试
tree = AVLTree([i for i in range(0, 100, 2)])
tree.pre_order(tree.root)
print("")
tree.in_order(tree.root)
print("")
tree.insert_no_rec(5)
tree.in_order(tree.root)

通过这份完整的代码,读者可以更全面地了解AVL树的实现过程和平衡操作。在实际应用中,AVL树常用于需要高效搜索、插入和删除操作的场景。希望这份代码对读者学习数据结构和算法有所帮助。

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值