博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AVL树(平衡二叉树)
阅读量:5049 次
发布时间:2019-06-12

本文共 4639 字,大约阅读时间需要 15 分钟。

定义及性质

  AVL树:AVL树是一颗自平衡的二叉搜索树.

  AVL树具有以下性质:

    根的左右子树的高度只差的绝对值不能超过1

    根的左右子树都是 平衡二叉树(AVL树)

 

百度百科:

  平衡二叉搜索树(Self-balancing binary search tree)又被称为AVL树(有别于AVL算法)

    且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

    平衡二叉树的常用实现方法有、、、、等。

       最小二叉平衡树的节点总数的公式如下 F(n)=F(n-1)+F(n-2)+1 这个类似于一个递归的,

       可以参考Fibonacci(斐波那契)数列,1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量。

 

AVL树--插入操作

AVL插入--旋转

代码实现

 

from bst import BST, BiTreeNodeclass AVLNode(BiTreeNode):    def __init__(self, data):        BiTreeNode.__init__(self, data)        self.bf = 0class 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        # 更新bf        if c.bf == 0:            p.bf = 1            c.bf = -1        else:            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        # update bf        if c.bf == 0:            p.bf = -1            c.bf = 1        else:            p.bf = 0            c.bf = 0        return c    def rotate_right_left(self, p, c):        g = c.lchild        s3 = g.rchild        c.lchild = s3        if s3:            s3.parent = c        g.rchild = c        c.parent = g        s2 = g.lchild        p.rchild = s2        if s2:            s2.parent = p        g.lchild = p        p.parent = g        # 更新 bf        if g.bf > 0:  # g.bf == 1            p.bf = -1            c.bf = 0        elif g.bf == 0:            p.bf = 0            c.bf = 0        else: # g.bf == -1            p.bf = 0            c.bf = 1        g.bf = 0        return g    def rotate_left_right(self, p, c):        g = c.rchild        s3 = g.lchild        c.rchild = s3        if s3:            s3.parent = c        g.lchild = c        c.parent = g        s2 = g.rchild        p.lchild = s2        if s2:            s2.parent = p        g.rchild = p        p.parent = g        # 更新 bf        if g.bf < 0:  # g.bf == 1            p.bf = 1            c.bf = 0        elif g.bf == 0:            p.bf = 0            c.bf = 0        else:  # g.bf == -1            p.bf = 0            c.bf = -1        g.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        # 更新bf        while node.parent:            if node.parent.lchild == node:  # 左孩子                if node.parent.bf < 0: # node.parent.bf=-2 左边深                    g = node.parent.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: # node.parent.bf=2 右边深                    g = node.parent.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 node.parent == g.lchild:                    g.lchild = n                else:                    g.rchild = n                break            else:                self.root = n                breaktree = AVLTree([7,3,5,4,2,8,6,9,1])tree.pre_order(tree.root)print("")tree.in_order(tree.root)

 

转载于:https://www.cnblogs.com/xiao-xue-di/p/10169711.html

你可能感兴趣的文章
一、记录Git使用中遇到的问题及解决方法
查看>>
学习网址
查看>>
前端表格插件datatables
查看>>
内部类
查看>>
树链剖分入门
查看>>
图解算法时间复杂度
查看>>
UI_搭建MVC
查看>>
一个样例看清楚JQuery子元素选择器children()和find()的差别
查看>>
代码实现导航栏分割线
查看>>
Windows Phone开发(7):当好总舵主 转:http://blog.csdn.net/tcjiaan/article/details/7281421...
查看>>
VS 2010打开设计器出现错误
查看>>
SQLServer 镜像功能完全实现
查看>>
Vue-详解设置路由导航的两种方法
查看>>
一个mysql主从复制的配置案例
查看>>
大数据学习系列(8)-- WordCount+Block+Split+Shuffle+Map+Reduce技术详解
查看>>
dvwa网络渗透测试环境的搭建
查看>>
Win8 安装VS2012 和 Sql Server失败问题
查看>>
过点(2,4)作一直线在第一象限与两轴围成三角形,问三角形面积的最小值?...
查看>>
java aes CBC的填充方式发现
查看>>
使用ionic cordova build android --release --prod命令打包报有如下错误及解决方法
查看>>