博客
关于我
AVL树的实现(图文详解)
阅读量:775 次
发布时间:2019-03-24

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

AVL树的实现

AVL树定义

AVL树是一种特殊的二叉搜索树,其设计目的是为了在数据较为有序的情况下,确保查找操作的平均复杂度仍然为O(log n)。与普通二叉搜索树不同,AVL树规定了一些平衡条件,通过定期旋转节点,避免树的高度差异过大。

为什么需要AVL树

发现普通二叉搜索树在数据有序或接近有序的情况下,会逐渐变成一条链状的树,导致查找操作的时间复杂度从理论上的O(log n)退化到实际上的O(n)。为了解决这一问题,AVL树通过严格控制子树高度差异不超过1,保证树的高度并不偏差太大。

AVL树平衡条件

AVL树的平衡条件可以通过平衡因子(balance factor, bf)来衡量。平衡因子定义为“右子树高度 - 左子树高度”。AVL树的平衡因子范围限制在-1、0、1三者之间。

AVL树结构

AVL树的结构与普通二叉搜索树类似,只是在每个节点中增加了平衡因子bf。具体结构定义包括:

  • 左右子树均为AVL树。
  • 平衡因子bf为整型值,值域为-1、0、1。
  • 右子树层数 - 左子树层数 = bf。
  • AVL树的旋转

    AVL树的插入操作通过旋转节点来维持平衡条件,主要有以下几种旋转方式:

    左单旋(Left Rotation)

    新节点插入较高右子树的右侧,需要将该子树向左转动一次。

    右单旋(Right Rotation)

    新节点插入较高左子树的左侧,需要将该子树向右转动一次。

    左右双旋(Left-Right Rotation)

    新节点插入较高左子树的右侧,需要同时进行左旋和右旋。

    右左双旋(Right-Layer Rotation)

    新节点插入较高右子树的左侧,需要同时进行右旋和左旋。

    AVL树插入

    插入步骤如下:

  • 先搜索找到合适的插入位置。
  • 插入新节点。
  • 调整上级节点的平衡因子。
  • 如果平衡因子超出范围(即绝对值大于1),启动旋转调整平衡。
  • 平衡因子调整

    • 新加入的节点会影响父节点的平衡因子。
    • 若父节点平衡因子为1或-1,需要向上调整。
    • 当父节点平衡因子为2或-2时,需要进行旋转调整。

    旋转案例

  • 右旋(Right Rotate)

    • 当新节点在左子树的右侧时,需要将左子树整体向右旋转。
  • 左旋(Left Rotate)

    • 当新节点在右子树的左侧时,需要将右子树整体向左旋转。
  • 左右双旋

    • 新节点插入左子树的右侧,首先左旋再向右旋。
  • 右左双旋

    • 新节点插入右子树的左侧,首先右旋再向左旋。
  • 代码测试

    顺序插入5,3,1

    当插入数字1时,触发右旋调整。

    随机插入10个数

    构建一个AVL树,确保树高的绝对差异不超过1。

    平衡验证

    int Height(Node* root) {    if (!root) return 0;    return (Height(root->_left) > Height(root->_right)) ? (Height(root->_left) + 1) : (Height(root->_right) + 1);}bool is_balance() {    return is_balance(_root);}bool is_balance(Node* root) {    if (!root) return true;    if (Height(root->_left) - Height(root->_right) != root->_bf)        cout << "No AVL Tree" << endl;    return false;    // 检查子树平衡,同时维持自己的平衡条件    return abs(root->_bf) <= 1 && is_balance(root->_left) && is_balance(root->_right);}

    通过上述验证方法,可以确认AVL树是否满足平衡条件。

    转载地址:http://weskk.baihongyu.com/

    你可能感兴趣的文章
    Netty常用组件一
    查看>>
    Netty常见组件二
    查看>>
    netty底层源码探究:启动流程;EventLoop中的selector、线程、任务队列;监听处理accept、read事件流程;
    查看>>
    Netty心跳检测
    查看>>
    Netty心跳检测机制
    查看>>
    netty既做服务端又做客户端_网易新闻客户端广告怎么做
    查看>>
    Netty核心模块组件
    查看>>
    Netty框架内的宝藏:ByteBuf
    查看>>
    Netty框架的服务端开发中创建EventLoopGroup对象时线程数量源码解析
    查看>>
    Netty源码—1.服务端启动流程一
    查看>>
    Netty源码—1.服务端启动流程二
    查看>>
    Netty源码—2.Reactor线程模型一
    查看>>
    Netty源码—2.Reactor线程模型二
    查看>>
    Netty源码—3.Reactor线程模型三
    查看>>
    Netty源码—4.客户端接入流程一
    查看>>
    Netty源码—4.客户端接入流程二
    查看>>
    Netty源码—5.Pipeline和Handler一
    查看>>
    Netty源码—5.Pipeline和Handler二
    查看>>
    Netty源码—6.ByteBuf原理一
    查看>>
    Netty源码—6.ByteBuf原理二
    查看>>