博客
关于我
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/

    你可能感兴趣的文章
    nginx 常用指令配置总结
    查看>>
    Nginx 常用配置清单
    查看>>
    nginx 常用配置记录
    查看>>
    nginx 开启ssl模块 [emerg] the “ssl“ parameter requires ngx_http_ssl_module in /usr/local/nginx
    查看>>
    Nginx 我们必须知道的那些事
    查看>>
    Nginx 的 proxy_pass 使用简介
    查看>>
    Nginx 的配置文件中的 keepalive 介绍
    查看>>
    Nginx 结合 consul 实现动态负载均衡
    查看>>
    Nginx 负载均衡与权重配置解析
    查看>>
    Nginx 负载均衡详解
    查看>>
    nginx 配置 单页面应用的解决方案
    查看>>
    nginx 配置https(一)—— 自签名证书
    查看>>
    nginx 配置~~~本身就是一个静态资源的服务器
    查看>>
    Nginx 配置清单(一篇够用)
    查看>>
    Nginx 配置解析:从基础到高级应用指南
    查看>>
    nginx+php的搭建
    查看>>
    nginx+tomcat+memcached
    查看>>
    nginx+Tomcat性能监控
    查看>>
    nginx+uwsgi+django
    查看>>
    Nginx-http-flv-module流媒体服务器搭建+模拟推流+flv.js在前端html和Vue中播放HTTP-FLV视频流
    查看>>