AVL/B-/+ Tree查找

news2024/9/24 19:13:33

文章目录

  • 0 树表的查找
  • 1 二叉排序树
    • 1.1 二叉排序树的操作
      • 1.1.1 二叉排序树的存储
      • 1.1.2 二叉排序树的递归查找
      • 1.1.3 二叉排序树的插入
      • 1.1.4 二叉排序树的生成
      • 1.1.5 二叉排序树的删除
    • 1.2 二叉排序树的查找性能分析
  • 2 平衡二叉树(AVL树)
    • 2.1 失衡二叉排序树的分析与调整
      • 2.1.1 LL型调整
      • 2.1.2 RR型调整
      • 2.1.3 LR型调整
      • 2.1.4 RL型调整
  • 3 根据以上几种类型构造AVL树

0 树表的查找

前面的Blog记录了二分查找,但是二分查找要求的是有序的,才能完成。有时非有序的不太方便,就可以采用动态查找表,也就是树表。
在这里插入图片描述

1 二叉排序树

二叉排序树(Binary Sort Tree)又称为二叉搜索树、二叉查找树。
定义:
二叉排序树或是空树,或是满足如下性质的二叉树:

  1. 若其左子树非空,则左子树上所有结点的值均小于根结点的值
  2. 若其右子树非空,则右子树上所有结点的值均大于等于根结点的值
  3. 左右子树本身又各是一棵二叉排序树

左小右大,左 < 根 < 右

在这里插入图片描述
第一个图是二叉排序树,左子树上的节点的值都小于根节点45,右子树上的节点都大于根节点45。第二幅图当中,左子树没有,右子树中所有单词的首字母都是大于等于根节点,所以也是二叉排序树。第三个和第四个例子当中,因为下面的一个节点大于根节点,所以不满足条件。

在这里插入图片描述
中序遍历非空的二叉排序树所得到的数据元素序列是一个按关键字排列的递增有序序列

1.1 二叉排序树的操作

假如所需要查找的对象比当前的根节点来的小,就只需要查找左子树,比根节点来的大,就去右子树找,等于根节点,就直接返回根节点。
在这里插入图片描述

1.1.1 二叉排序树的存储

typedef struct
{
    KeyType key; //关键字项
    InfoType otherinfo; //其他数据域
}ElemType;

typedef struct BSTNode
{
    ElemType data; //数据域
    struct BSTNode *lchild, *rchild; //左孩子右孩子指针
}BSTNode, *BSTree;

BSTree T;//定义二叉排序树

1.1.2 二叉排序树的递归查找

在这里插入图片描述
左右子树都是调用自身的算法去查找。

BSTree SearchBST(BSTree T, KeyType key)
{
	if((!T)||key == T->data.key)
	{
		return T;
	}
	else if(key < T->data.key)
	{
		return SearchBST(T->lchild, key);//在左子树中继续查找
	}
	else
	{
		return SearchBST(T->rchild, key);//在右子树中继续查找
	}
}

1.1.3 二叉排序树的插入

在这里插入图片描述

要插入的节点比根节点小,就放在左孩子,之后再与左孩子当中的根节点继续进行比较。比根节点大,则放入右孩子,再继续进行比较。
思想
在这里插入图片描述
插入的节点一定是在叶节点上。

1.1.4 二叉排序树的生成

在这里插入图片描述
一个无序序列可通过构道二叉排序树而变成一个有序序列,构造树的过程就是对无序序列进行排序的过程(中序遍历)。
插入的结点均为叶子结点,故无需移动其他结点。相当于在有序序列上插入记录而无需移动其他记录。
但是:
关键字的输入顺序不同,建立的不同的二叉排序树。
在这里插入图片描述
形态不一样,那么查找效率就不一样。

1.1.5 二叉排序树的删除

在这里插入图片描述
最重要的就是最后两条。

删除的是叶子节点的话,直接删除。
在这里插入图片描述
在这里插入图片描述
20和88直接删除,,修改双亲的左右孩子即可。
把其双亲结点中相应指针域的值改为“空“

被删除的结点只有左子树或者只有右子树,用其左子树或者右子树替换它(结点替换)
在这里插入图片描述
在这里插入图片描述
直接修改双亲指针,使双亲直接指向被删除节点的左右孩子即可。

被删除的结点既有左子树,也有右子树
在这里插入图片描述
这种情况,仍然要保持中序遍历是有序的,该怎么做?
一种方法就是用其中序遍历的前驱节点来代替他。这样仍然能保持中序遍历不变,所以去找其左子树,与其挨得最近的一个节点进行代替,这里也就是用40来代替50。
在这里插入图片描述
当然了,也可以用其后继替换之,然后再删除该后继结点。后继是右子树中最小的结点。这里就是把80替换50,80成为根节点后直接一条线指向90。

在这里插入图片描述
一些例子。
在这里插入图片描述

1.2 二叉排序树的查找性能分析

每一个节点需要查找几次,与这个节点所在二叉排序树的层次有关。二叉排序树上查找某关键字等于给定值的结点过程,其实就是走了一条从根到该结点的路径。
综上得出,比较的关键字次数 = 此节点所在的层次数

在这里插入图片描述

层数上的规定,最好不要超过 l o g 2 n + 1 log_2n+1 log2n+1层,最坏的情况大为 n n n层,即为右边图的那种情况。

在这里插入图片描述
层数最多的情况下,ASL是与顺序查找时是一样的。
在这里插入图片描述

2 平衡二叉树(AVL树)

问题:如何提高形态不均衡的二叉排序树的查找效率?
解决办法:做“平衡化”处理,即尽量让二叉树的形状均衡!这就是平衡二叉树的由来。

在这里插入图片描述

为了方便起见,给每个结点附加一个数字,给出该结点左子树与右子树的高度差。这个数字称为结点的平衡因子(BF)
平衡因子=结点左子树的高度-结点右子树的高度

根据平衡二叉树的定义,平衡二叉树上所有结点的平衡因子只能是-1,0,1。
绝对值小于等于1 ,不超过1。

在这里插入图片描述
对于一棵有 n n n个结点的AVL树,其高度保持在 O ( l o g 2 n ) O(log_2n) O(log2n)数量级,ASL也保持在 O ( l o g 2 n ) O(log_2n) O(log2n)量级。

2.1 失衡二叉排序树的分析与调整

在这里插入图片描述
如果在一棵AVL树中插入一个新结点后造成失衡,则必须重新调整树的结构,使之恢复平衡。(上图的53节点就失衡了)

在这里插入图片描述
如果发现插入节点后,不止一个失衡的结点时,就找一个最小失衡子树的根节点作为失衡节点。
在这里插入图片描述
在这里插入图片描述
调整原则:

  1. 降低高度
  2. 保持二叉排序树性质(左子树比根节点小,右子树比根节点大),所以最小的放在最左边。

2.1.1 LL型调整

在这里插入图片描述
LL型就是插入一个新节点,这个新节点的插入位置就是在失衡节点的左子树的左子树上面。

调整:
将A节点降下来,B节点升上去。
或者是平衡旋转的方法,直接转下来。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.1.2 RR型调整

RR型就是插入一个新节点,这个新节点的插入位置就是在失衡节点的右子树的右子树上面。
在这里插入图片描述
思路还是降高度。在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
举例:
在这里插入图片描述
解答:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.1.3 LR型调整

LR型就是插入一个新节点,这个新节点的插入位置就是在失衡节点的左子树的右子树上面。
在这里插入图片描述
调整还是按照原则。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第三步这样放是为了保持AVL树的特性。
在这里插入图片描述

2.1.4 RL型调整

RL型就是插入一个新节点,这个新节点的插入位置就是在失衡节点的右子树的左子树上面。
在这里插入图片描述
与LR树类似。
在这里插入图片描述
在这里插入图片描述

3 根据以上几种类型构造AVL树

在这里插入图片描述
插入7时,发现是LR类型,所以根据LR类型进行调整,即7节点上升,之后3和16分别作为其左子树与右子树。

在这里插入图片描述
此时又出现了LL型,直接将中间节点11上升,然后一个作为其左孩子,一个作为其右孩子。在这里插入图片描述
之后插入26节点,发现出现了RR失衡。
在这里插入图片描述
在这里插入图片描述
之后又出现了RL失衡。
在这里插入图片描述
RL与LR就是把处在中间值的提上去,然后其余两个作为左子树与右子树。
在这里插入图片描述
在这里插入图片描述
3个顶点失衡,调整最小的那一颗子树。,即红色颜色标注的,此为LR型失衡。在这里插入图片描述
至此,AVL树构造完毕。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/806300.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WEB:web2

背景知识 代码审计 题目 由上述可知&#xff0c;这段代码定义了一个函数encode&#xff0c;接受一个字符串参数$str&#xff0c;并返回对其进行加密后的结果 加密算法包括&#xff1a; 使用strrev函数将字符串进行翻转&#xff1b;对翻转后的每个字符&#xff0c;将其ASCII值…

【playbook】Ansible的脚本----playbook剧本

Ansible的脚本----playbook剧本 1.playbook剧本组成2.playbook剧本实战演练2.1 实战演练一&#xff1a;给被管理主机安装Apache服务2.2 实战演练二&#xff1a;使用sudo命令将远程主机的普通用户提权为root用户2.3 实战演练三&#xff1a;when条件判断指定的IP地址2.4 实战演练…

企业如何制定数字化管理决策方案

数字化管理决策是指通过利用数字技术和数据分析来辅助和支持管理决策的过程。它利用计算机、互联网和其他技术来收集、分析和解释大量的数据&#xff0c;从而帮助管理者做出更准确、更有效的决策。 数字化管理决策的关键 数据收集与分析&#xff1a;数字化管理决策依赖于数据…

FreeRTOS之队列

什么是队列&#xff1f; 队列又称消息队列&#xff0c;是一种常用于任务间通信的数据结构&#xff0c;队列可以在任务与任务间、中断和任 务间传递信息。 关于队列的几个名词&#xff1a; 队列项目&#xff1a;队列中的每一个数据&#xff1b; 队列长度&#xff1a;队列能够…

PHP生成动态小程序二维码自定义路径和参数

PHP生成动态小程序二维码自定义路径和参数 小程序路径src 参数params http://test.com?srcindex/index/index&paramsstore_id10<?php $src$_GET[src]; $params$_GET[params];doPageNewQr($src,$params); function doPageNewQr($src,$params){//配置APPID、APPSECRET$A…

品牌触点:特别关注消费者的关键接触点

品牌触点&#xff1a;特别关注消费者的关键接触点 有个专门岗位&#xff1a;触点经理 打造品牌是超级工程 关键触点要持久不断地努力 很受启发 趣讲大白话&#xff1a;让消费者见一次喜欢一次 【趣讲信息科技240期】 **************************** 品牌触点是品牌与消费群体接触…

2023-将jar包上传至阿里云maven私有仓库(云效制品仓库)

一、背景介绍 如果要将平时积累的代码工具jar包&#xff0c;上传至云端&#xff0c;方便团队大家一起使用&#xff0c;一般的方式就是上传到Maven中心仓库&#xff08;但是这种方式步骤多&#xff0c;麻烦&#xff0c;而且上传之后审核时间比较长&#xff0c;还不太容易通过&a…

Spring 6【数据绑定之类型转换(Type Conversion)】(十一)-全面详解(学习总结---从入门到深化)

目录 数据绑定之类型转换(Type Conversion) 数据绑定之类型转换(Type Conversion) 1.PropertyEditor 在Spring框架3.0之前并没有提供类型转换器&#xff0c;而是使用JDK原生的java.beans.PropertyEditor进行类型转换&#xff08;提供了PropertyEditor接口的几个实现类&#x…

指令调度(Instruction Scheduling)

指令调度&#xff08;Instruction Scheduling&#xff09; 指令调度的约束基本机器模型基本块调度全局调度 指令调度是为了提高指令级并行&#xff08;ILP&#xff09;&#xff0c;对于超长指令字&#xff08;VLIW, Very Long Instruction Word&#xff09;和多发射系统&#x…

Jvm的一些技巧

反编译字节码文件 找到对应的class文件所在的目录&#xff0c;使用javap -v -p 命令 查询运行中某个Java进程的Jvm参数 【案例】查询 MethodAreaDemo 这个类运行过程中&#xff0c;初始的元空间大小 MetaspaceSize jps 查询 Java 进程的进程ID ![在这里插入图片描述](https…

GRACE数据反演的新理解

一、问题提出 “重力恢复与气候实验”&#xff08;GRACE&#xff09;为监测地球系统内全球大尺度质量变化提供了一种新途径。自2002年3月发射以来&#xff0c;GRACE一直在生成时间变化的重力场模型&#xff0c;这些模型可用于量化与全球气候变化相关的地球系统不同组成部分内的…

【C++11】——类的新功能

目录 1. 默认成员函数 2. 类成员变量初始化 3. 强制生成默认函数的关键字default 4. 禁止生成默认函数的关键字delect 5. 继承和多态的final与override关键字 6. 测试案例 1. 默认成员函数 原来C类中&#xff08;C11之前&#xff09;&#xff0c;有6个默认成员函数&…

管理类联考——写作——素材篇——论证有效性分析——常见逻辑谬误

批判性思维常见逻辑谬误 有些错误出现在我们澄清或定义某个观点的时候&#xff0c;有些错误出现在我们收集证据或者用证据和理由支撑某个观点的时候&#xff0c;有些错误出现在我们尝试从证据得出结论的时候&#xff0c;有些错误甚至出现在我们评估他人的观点或者理由的时候。…

Drools用户手册翻译——第四章 Drools规则引擎(八)drools中的事实传播模式和议程评估过滤器

甩锅声明&#xff1a;本人英语一般&#xff0c;翻译只是为了做个笔记&#xff0c;所以有翻译错误的地方&#xff0c;错就错了&#xff0c;如果你想给我纠正&#xff0c;就给我留言&#xff0c;我会改过来&#xff0c;如果懒得理我&#xff0c;就直接划过即可。 drools中的事实…

微信小程序开发每日一写--5

按钮的使用和底层逻辑的实现&#xff08;暂未成功&#xff09; WXML&#xff1a; <button class"bth1"type"primary" >按钮</button>JS&#xff1a; // index.js // 获取应用实例 //const app getApp() Page({/*bthTapHandler(e){//按钮的…

C动态内存分配

&#x1f388;对比一般内存分配和动态内存分配 &#x1f308;一般内存分配 int val 20; char arr[10] {0};特点&#xff1a; ①大小是固定的&#xff0c;一旦分配好就无法改变&#xff08;数组必须指定大小后编译器才能分配空间&#xff09; ②分配的空间具体放置什么类型的…

ffmpeg批量分割视频解决视频前几秒黑屏的问题解决

echo 请输入视频地址&#xff1a; set /p fp echo 请输入开始时间&#xff1a; set /p st echo 请输入结束时间&#xff1a; set /p et echo 请输入分片时间&#xff1a; set /p sgt echo 注意&#xff1a;循环范围参数要空格。 for /l %%i in (%st%, %sgt%, %et%) do call :aa…

【Spring AOP学习】AOP的组成 SpringAOP的实现和实现原理

目录 一、认识SpringAOP 1、AOP是什么&#xff1f; 2、AOP的功能 3、AOP的组成&#xff08;重要&#xff09; 二、SpringAOP的实现 &#x1f337;1、添加Spring AOP框架支持 &#x1f337;2、定义切面和切点 &#x1f337; 3、定义通知 3.1 完成代码实现 3.2 具体通知…

目前可以实现用手机操作水质自动采样器吗

利用自动采样器进行水样采集可以说节省很大的人力物力&#xff0c;但是有时为了采到更具代表性的水样&#xff0c;我们需要对沟渠、深井、排污口等特殊场景进行采样。像这些狭小的空间领域采样就有点困难&#xff0c;对现场工作人员就带来了一些难题。所以也需要一款可以在井下…

HCIP——OSPF的防环机制

OSPF的防环机制 一、域间防环二、域内防环有向图转化1、有向图的画法2、示例&#xff1a; 三、SPF算法 OSPF将整个OSPF域划分为多个区域&#xff0c;区域内部通过拓扑信息计算路由&#xff0c;区域间传递路由信息&#xff0c;实现全网可达。OSPF防环机制主要是体现在域内防环和…