学习平衡搜索二叉树(AVL树)【日志】

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 学习平衡搜索二叉树(AVL树)【日志】

AVL树的概念:

我们都知道搜索二叉树是 小的数据在当前根节点的左边 大的数据在根节点的右边 。虽说这种结构在查找数据的时候会很方便,但是如果现在我们的数据是接近有序的那么,这个二叉树就可能退化成为单支树 这样我们的查找效率并没有得到改善 此时我们称这种情况为不平衡,所以就有了现在的平衡二叉树保障了搜索的效率


现在我们就可以通过保证 左右子树高度差(右减去左)不超过-1和1 和 左右子树都为AVL树来 实现我们整体的AVL树

选择实现的方法不只一种 可选择用平衡因子的方式,这个到底最终也只是以个实现的选择


实现AVL树:

要实现一个AVL树,那么就需要控制好在对它操作时,节点之间的平衡关系,那这个就需要根据不同的情况进行对应的旋转操作!!!


插入:

我们首先插入的规则肯定还是按照搜索二叉树的规则来的,可是插完数据后又该怎样更新平衡因子呢,又该怎样进行旋转呢?这些都是在插入操作时需要考虑的问题。


对于更新平衡因子,这个在我们组织节点的时候就应该考虑到,因为当我们插入一个节点后平衡因子影响的是自己的祖先,所以我们采用的是三叉链的结构(也就是多一个指针指向父亲节点)这样也方便我们回溯去更新平衡因子

① 如何更新一个节点平衡因子就只需要看新插入节点在这个节点的左子树还是右子树就可以啦

ac3ec8da4d2d45f8a3caa2fa93fb6ef6.jpg

在右子树就+1 在左子树就-1 如果在更新过程中发现更新后的平衡因子违反规则那么就要对其进行旋转调整 一定要注意自己 子树高度 是否有变化 没有变化就没必要再往上更新了


旋转:

旋转的原则:遵守规则,恢复平衡

右边高--左单旋

大家看这个图片里的样例违规了嘛?

7adf8fccfc224553b8f7875598c6dd65.jpg

违规了!!! 这里是很明显的根节点的右边子树高了:应该左单旋


b8b3e7ec9935454cbc455a7e084375fe.gif

void RotateL(node* parent)
  {
    node* cur = parent->_right;
    node* curL = cur->_left;
    parent->_right = curL;
    if (curL)           //left可能为空
      curL->_parent = parent;
    node* tmpNode = parent->_parent;
    //已保存,可更改parent的父节点
    parent->_parent = cur;
    cur->_left = parent;
    if (parent == _root)
    {
      cur = _root;
      cur->_parent = nullptr;
    }
    else
    {
      if (tmpNode->_left == parent)
      {
        tmpNode->_left = cur;
      }
      else
      {
        tmpNode->_right = cur;
      }
      cur->_parent = tmpNode;
    }
        cur->_vb = 0;
        parent->_vb =0;//更新平衡因子 
  }

在写这部分的代码的时候,要小心一些,有些节点是有可能是为空的,又因为这个是一个三叉链,也要注意注意父亲节点的更新,以及更新前状态的保存

对于左边高--右单旋也是一样的:

b607341da0ad47fcb96d0746a5e237fa.gif

代码的实现原理和左单选是一样的!!!!(这个大家可以自己尝试一下)


双旋:

这个实现起来并不复杂,但是要注意双选后平衡因子的更新!!


0d72e98fb9df4691b927efc626ac3f23.jpg大家看这幅图,觉得应该怎样的旋转呢?

df957a02407e459a963853c26df348b0.gif

面对这种情况,其实就先进行左单旋,这样我们就能明显发现现在的情况已经是一个明显的左边高需要右单旋的情况。 当然与之相同的也有右左双旋

大家看下面这三张图就知道为什么平衡因子会需要注意了


faa4f44d50fe4c6e925fe4a23f4a6ec0.jpg

2e402b88476742f390d2e74d5e4ae946.jpg

54f1e50227aa4939aa44771e431f26fc.jpg


明明都是双旋为什么平衡因子不一样呢:我们进行了两次单旋,那么就肯定有两个子树移接到其他子树上了,也就代表平衡因子也会跟着发生对应的变化 所以我们在更新平衡因子的时候也得注意

void RotateLR(node* parent)
  {
    node* cur = parent->_left;
    node* curR = cur->_right;
    int bf = curR->_vb;
    LotateR(cur);
    RotateL(parent);
    if (bf == 0)
    {
      parent->_vb = 0;
      cur->_vb = 0;
      curR->_vb = 0;
    }
    else if (bf == 1)
    {
      cur->_vb = -1;
      curR->_vb = 0;
      parent->_vb = 0;
    }
    else if (bf == -1)
    {
      cur->_vb = 0;
      curR->_vb = 0;
      parent->_vb = 1;
    }
    else
    {
      assert(false);
    }
  }

除了上面的左右双旋 还有 右左双旋 实现的思路都是一样的,所以大家可以自己下来推导一下!!

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
6月前
|
JSON Prometheus Cloud Native
Grafana 系列 - 统一展示 -8-ElasticSearch 日志快速搜索仪表板
Grafana 系列 - 统一展示 -8-ElasticSearch 日志快速搜索仪表板
|
3月前
|
存储 搜索推荐 大数据
阿里泛日志设计与实践问题之schema-on-read技术的发展对日志搜索的影响是啥,如何解决
阿里泛日志设计与实践问题之schema-on-read技术的发展对日志搜索的影响是啥,如何解决
|
22天前
|
Arthas 监控 Java
JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
这篇文章全面介绍了JVM的命令行参数、GC日志分析以及性能调优的各个方面,包括监控工具使用和实际案例分析。
37 3
|
27天前
|
存储 Prometheus NoSQL
大数据-44 Redis 慢查询日志 监视器 慢查询测试学习
大数据-44 Redis 慢查询日志 监视器 慢查询测试学习
22 3
|
1月前
|
数据采集 监控 Java
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
本文是关于SpringBoot日志的详细教程,涵盖日志的定义、用途、SLF4J框架的使用、日志级别、持久化、文件分割及格式配置等内容。
78 0
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
|
2月前
|
Kubernetes API Docker
跟着iLogtail学习容器运行时与K8s下日志采集方案
iLogtail 作为开源可观测数据采集器,对 Kubernetes 环境下日志采集有着非常好的支持,本文跟随 iLogtail 的脚步,了解容器运行时与 K8s 下日志数据采集原理。
|
22天前
|
Python
log日志学习
【10月更文挑战第9天】 python处理log打印模块log的使用和介绍
20 0
|
3月前
|
JSON 中间件 Go
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
本文详细介绍了如何在Go项目中集成并配置Zap日志库。首先通过`go get -u go.uber.org/zap`命令安装Zap,接着展示了`Logger`与`Sugared Logger`两种日志记录器的基本用法。随后深入探讨了Zap的高级配置,包括如何将日志输出至文件、调整时间格式、记录调用者信息以及日志分割等。最后,文章演示了如何在gin框架中集成Zap,通过自定义中间件实现了日志记录和异常恢复功能。通过这些步骤,读者可以掌握Zap在实际项目中的应用与定制方法
122 1
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
|
3月前
|
Java 数据库连接 数据库
后端框架的学习----mybatis框架(6、日志)
这篇文章介绍了如何在MyBatis框架中使用日志功能,包括配置MyBatis的日志实现、使用log4j作为日志工具,以及如何通过配置文件控制日志级别和输出格式。
|
5月前
|
网络安全 数据安全/隐私保护 网络虚拟化
神州数码DCWS学习日志(二)
神州数码DCWS学习日志
27 1