数据结构与算法:树形查找

news2024/9/20 18:36:50

一.二叉排序树(BST)

1.个人理解

  • 左子树结点值 < 根结点值 < 右子树结点值
  • 对二叉排序树进行中序遍历,可以得到一个递增的有序数列

2.二叉树查找

原理:

对于一个给定的二叉排序树,如果要查找一个节点,可以按照以下步骤进行:

  1. 从根节点开始比较。
  2. 如果要查找的值等于当前节点的值,则找到了目标节点,返回该节点。
  3. 如果要查找的值小于当前节点的值,则在左子树中继续查找。
  4. 如果要查找的值大于当前节点的值,则在右子树中继续查找。
  5. 如果在整棵树中都没有找到目标节点,则返回空指针或者抛出异常表示未找到。

时间复杂度为O(log n),其中n为树中节点的数量,因为每次查找都会将搜索范围缩小一半。

3.查找算法实现

//在二叉排序树中查找值为key的结点
BSTNode *BST_ _Search(BSTree T,int key){
	while(T!=NULL&&key!=T->key){ 
	//若树空或等 于根结点值,则结束循环
	if(key<T->key) 
		T=T->lchild;                  //小于,则在左子树上查找
	else 
		T=T->rchild;                  //大于,则在右子树上查找
	}
	return T;
}

这个过程显然是一个递归的过程,可以使用递归来完成查找,这里并没有使用递归,递归算法编写请参考【递归算法】

4.二叉排序树插入

原理:

若原二叉排序树为空,则直接插入结点:否则,若关键字k小于根结点值,则插入到左子树,若关键字k大于根结点值,则插入到右子树。

算法实现:

//在二叉排序树插入关键字为k的新结点(递归实现)
int BST_ Insert(BSTree &T, int k){
	if(T==NULL){                        //原树为空, 新插入的结点为根结点
		T=(BSTree)malloc(sizeof(BSTNode));
		T->key=k;
		T->lchild=T->rchild=NULL
		return 1;                      //返回1,插入成功
	}
	else if(k==T->key)                  //树中存在相同关键字的结点,插入失败
		return 0;
	else if(k<T->key)                   //插入到T的左子树
	return BST_ Insert(T->lchild,k);
else                                    //插入到T的右子树
	return BST_ Insert(T->rchild,k);
}

5.二叉排序树删除

二叉排序树的删除操作需要分为以下几个步骤:

  1. 查找待删除节点:从根节点开始,比较待删除节点的关键字和当前节点的关键字,如果相等,则找到了待删除节点;否则,继续在左子树或右子树中查找。

  2. 分情况讨论:

    a. 待删除节点没有左右子树:直接删除该节点即可;

    b. 待删除节点只有左子树或右子树:将待删除节点的左子树或右子树挂在其父节点的相应位置上,并删除待删除节点;

    c. 待删除节点既有左子树又有右子树:找到待删除节点的中序遍历的前驱或后继节点(即比待删除节点小的最大节点或比待删除节点大的最小节点),用前驱或后继节点的值替换待删除节点的值,然后将问题转化成删除前驱或后继节点。

  3. 如果删除的是根节点,则需要将新的根节点返回。

原理图:

wKjZ.jpg

代码可以参考数据结构专栏之树这一篇博客,我以后会写的。

二.平衡二叉树(AVL树)

1.平衡二叉树

平衡二叉树(Balanced Binary Tree),简称平衡树,是一种特殊的二叉查找树。它的特点是:任意节点的左右子树高度差不超过1,即每个节点的左右子树高度之差的绝对值都不超过1。这样可以保证查找、插入和删除等操作的时间复杂度为O(log n),提高了树的性能。

平衡二叉树的常见实现有AVL树、红黑树、B树等,其中AVL树是最早被发明的平衡树之一。AVL树要求每个节点的左右子树高度差的绝对值不超过1,并在插入或删除节点后通过旋转操作来自动调整树的结构以满足平衡条件。

平衡二叉树的优点是在保证基本的查找、插入、删除操作的时间复杂度为O(log n)的同时,还具有较好的空间利用率和较小的树高,适合存储大量数据的情况。缺点是相比于普通二叉查找树,平衡树的实现较为复杂,且维护平衡状态增加了插入、删除节点的开销。

2.平衡二叉树的插入

平衡二叉树的插入操作分为以下几步:

  1. 如果树为空,将要插入的节点作为根节点。
  2. 如果插入的元素小于当前节点的值,则在左子树上递归插入;如果插入的元素大于当前节点的值,则在右子树上递归插入。
  3. 在递归返回的过程中,检查当前节点是否失衡。如果当前节点失衡了,需要进行相应的旋转操作来恢复平衡。

对于平衡二叉树的旋转操作,有以下两种:

  1. 左旋转:对于节点 A,如果它的右子树比左子树高出 1 或者 2 层,那么进行左旋转。具体操作是,把 A 的右子节点作为新的根节点,A 变成新根节点的左子树,新根节点的原左子树变成 A 的新右子树。
  2. 右旋转:与左旋转类似,对于节点 A,如果它的左子树比右子树高出 1 或者 2 层,那么进行右旋转。具体操作是,把 A 的左子节点作为新的根节点,A 变成新根节点的右子树,新根节点的原右子树变成 A 的新左子树。

针对这一点,博主建议前往B站看一个五分钟的视频即可理解。

这里博主推荐一个视频,供大家参考:平衡二叉树的插入

3.平衡二叉树的删除

平衡二叉树的删除操作与普通二叉搜索树的删除操作相似,但需要在删除节点之后重新平衡树结构,以保证树的高度始终为 logn

具体的删除操作可以分为以下三个步骤:

  1. 定位待删除节点,并进行删除。如果待删除节点是叶子节点,则直接删除;如果待删除节点只有一个子节点,则将其子节点替换为自己即可;如果待删除节点有两个子节点,则找到其右子树的最小节点(或者左子树的最大节点),将其值赋给当前节点,然后删除这个右子树的最小节点(或左子树的最大节点)。
  2. 从删除节点的父节点开始向上回溯,更新祖先节点的平衡因子。如果发现某个祖先节点的平衡因子的绝对值大于1,则需要进行旋转操作使其重新平衡。
  3. 对于任何因为删除而导致失衡的子树,都要进行旋转操作,以恢复平衡。

具体的旋转操作包括左旋、右旋、左右旋和右左旋四种情况,不同的情况需要选择不同的旋转方式来达到平衡。其中左旋将左子树上移一层,右旋将右子树上移一层,左右旋将左子树先右旋再上移,右左旋将右子树先左旋再上移。

三.红黑树(RBT)

1.定义与性质

红黑树是一种自平衡二叉搜索树,它保证在最坏情况下基本动态集合操作的时间复杂度为 O(log n)。

红黑树的性质如下:

  1. 每个节点要么是红色,要么是黑色。
  2. 根节点是黑色的。
  3. 每个叶子节点(NIL节点)是黑色的。
  4. 如果一个节点是红色的,则它的两个子节点都是黑色的。
  5. 对于任意一个节点,从该节点到其所有后代叶子节点的简单路径上,均包含相同数目的黑色节点(即黑高相等)。

其中,性质 4 是红黑树与普通二叉搜索树的区别所在。这个性质保证了红黑树的黑高不会超过红高的两倍,从而保证了树的平衡性。

口诀:“左右根、根叶黑、不红红、黑路同。”

2.RBT插入

红黑树是一种自平衡的二叉搜索树,它保证了在最坏情况下基本动态操作(插入、删除、查找)的时间复杂度为 O(log n)。

红黑树的插入操作可以分为以下几个步骤:

  1. 将新节点插入到红黑树中,使用二叉搜索树基本插入操作。
  2. 将新节点标记为红色。
  3. 进行颜色调整,确保不破坏红黑树的五个性质。
    1. 父节点和子节点不能同时为红色。
    2. 根节点必须为黑色。
    3. 所有叶子节点都是黑色的空节点(NIL节点)。
    4. 从任一节点到其每个叶子节点的所有路径都包含相同数目的黑色节点。
    5. 每个红色节点必须有两个黑色子节点。

颜色调整包括三种情况:

第一种情况:新节点的父节点是黑色。这种情况下没有任何问题,直接返回即可。

第二种情况:新节点的父节点是红色,而且新节点的叔叔节点也是红色。这种情况下需要进行重新着色,将父节点和叔叔节点都变为黑色,祖父节点变为红色,然后把祖父节点作为新节点继续进行调整。

第三种情况:新节点的父节点是红色,而且新节点的叔叔节点是黑色或者空节点。这种情况下需要进行旋转操作,将当前节点和其父节点左旋或右旋,然后重新着色。

通过以上步骤,就可以完成红黑树的插入操作,并保证了红黑树的五个性质。

wEhg.jpg

四.比较分析

1.时间复杂度

wlvb.jpg

2.个人理解

平衡二叉树和红黑树本身都是一种二叉排序树,只是在此基础上增添了新的规则而已。

所以进行插入和删除操作时需要进行定位的方法也是二叉排序树使用的方法。

五.说明

新星计划:数据结构与算法,@西安第一深情,创作打卡3!

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

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

相关文章

并发知识杂谈

在JAVA语言层面&#xff0c;怎么保证线程安全&#xff1f; 有序性&#xff1a;使用happens-before原则 可见性&#xff1a;可以使用 volatile 关键字来保证&#xff0c;不仅如此&#xff0c;volatile 还能起到禁止指令重排的作用&#xff1b;另外&#xff0c; synchronized 和…

进程和编码

一、python代码的运行方式 1.脚本式 2. 交互式 一般用于代码的测试 二、进制及相互之间的转换 1. 进制 2.进制之间相互转换 在python中&#xff0c;十进制是以整形的形式存在&#xff0c;其他进制是已字符串的形式存在。 二进制/八进制/十六进制都可与十进制相互转换。但…

走向编程大师之路的几个里程碑

走向编程大师之路的几个里程碑 1语言关 2算法关 3系统关 4 编译器关 如下的系统的核心代码都有一万行以上&#xff0c;是规模和复杂度足够 大&#xff0c;可以检验开发者的模块化编程能力&#xff0c;掌控复杂度的能力。 使用什么编程语言本身是不重要的&#xff0c;能够有能…

常用消息中间件简介

一、 分布式系统消息通信技术简介 分布式系统消息通信技术主要包括以下几种&#xff1a; 1. RPC(Remote Procedure Call Protocol). 一般是C/S方式&#xff0c;同步的&#xff0c;跨语言跨平台&#xff0c;面向过程 2. CORBA(Common Object Request Broker Architecture). CO…

一个命令搞定Linux大文件下载

问题 Linux下log日志太大了&#xff0c;下载太慢了&#xff0c;即使下载下来&#xff0c;打开也费劲&#xff0c;咋办&#xff1f;将某文件夹打包成xx.tar.gz包&#xff0c;但依然很大&#xff0c;公司无法下载这么大的压缩包&#xff0c;咋办&#xff1f; split 以上2个问题…

[golang gin框架] 37.ElasticSearch 全文搜索引擎的使用

一.全文搜索引擎 ElasticSearch 的介绍&#xff0c;以 及安装配置前的准备工作 介绍 ElasticSearch 是一个基于 Lucene 的 搜索服务器,它提供了一个 分布式多用户能力的 全文搜索引擎&#xff0c;基于 RESTful web 接口,Elasticsearch 是用 Java 开发的&#xff0c;并作为 Apac…

PIC18F26单片机波特率配置

只需要配置以下三个寄存器&#xff1a; BRGCON1 BRGCON2 BRGCON3 BRGCON10x07; > 0000 0111 BRGCON20x90; > 1001 0000 BRGCON30x42; > 0101 0010 BRGCON1&#xff1a; Sync_Sog (bit7~bit6)1TQ,BRP(bit5~bit0)1 &#xff0c;则TQ((2*(BRP1))/Fosc16/32M&am…

Mysql存储时间,对应Api及对应的java属性

1.Mysql存储时间的类型 常用的储存时间/日期的类型&#xff1a; DATE&#xff1a;仅用于存储日期值&#xff08;年、月、日&#xff09;&#xff0c;格式为YYYY-MM-DD。TIME&#xff1a;仅用于存储时间值&#xff08;小时、分钟、秒&#xff09;&#xff0c;格式为HH:MM:SS。DA…

朴素贝叶斯算法实现英文文本分类

目录 1. 作者介绍2. 朴素贝叶斯算法简介及案例2.1朴素贝叶斯算法简介2.2文本分类器2.3对新闻文本进行文本分类 3. Python 代码实现3.1文本分类器3.2 新闻文本分类 参考&#xff08;可供参考的链接和引用文献&#xff09; 1. 作者介绍 梁有成&#xff0c;男&#xff0c;西安工程…

【UE】连续射击Niagara特效

效果 步骤 1. 新建一个粒子系统 选择“来自所选发射器的新系统” 添加“Fountain” 2. 打开这个新建的粒子系统 选中“Initialize Particle”模块&#xff0c;将颜色设置为&#xff08;100,0,0&#xff09; 再让生成的粒子大一些 选中“Spawn Rate”模块&#xff0c;将粒子的…

如何编写接口自动化框架系列之unittest测试框架的详解(二)

在编写自动化框架过程中 &#xff0c;我们首先想到的就是选择一个合适的测试框架 &#xff0c;目前常用的测试框架有unittest和pytest , unittest比较简单&#xff0c;适合入门着学习 &#xff1b;而pytest比较强大&#xff0c;适合后期进阶 。本文主要介绍的就是unittest框架 …

pytorch笔记(十)Batch Normalization

环境 python 3.9numpy 1.24.1pytorch 2.0.0+cu117一、Batch Normalize 作用 加快收敛、提升精度:对输入进行归一化,从而使得优化更加容易减少过拟合:可以减少方差的偏移可以使得神经网络使用更高的学习率:BN 使得神经网络更加稳定,从而可以使用更大的学习率,加速训练过程…

Chapter5: SpringBoot与Web开发2

接上一篇 Chapter4: SpringBoot与Web开发1 10. 配置嵌入式Servlet容器 SpringBoot默认采用Tomcat作为嵌入的Servlet容器&#xff1b;查看pom.xml的Diagram依赖图&#xff1a; 那么如何定制和修改Servlet容器的相关配置? 下面给出实操方案。 10.1 application.properties配…

依赖范围和编译classpath、测试classpath、运行classpath的关系

最近学习maven&#xff0c;这里看了下别人解释的区别原文&#xff0c;机翻一下&#xff0c;看的懵懵懂懂的 这其实应该是一个简单的区别&#xff0c;但我一直在Stackoverflow上回答一连串类似的问题&#xff0c;而人们往往会误解这个问题。 那么&#xff0c;什么是classpath&am…

[CF复盘] Codeforces Round 874 (Div. 3) 20230520】

[CF复盘] Codeforces Round 874 (Div. 3 20230520 总结A. Musical Puzzle![在这里插入图片描述](https://img-blog.csdnimg.cn/01ab8d835b4343659e8b80680dd9d639.png)2. 思路分析3. 代码实现 B. Restore the Weather1. 题目描述2. 思路分析3. 代码实现 C. Vlad Building Beaut…

FinClip | 2023 年 4 月产品大事记

我们的使命是使您&#xff08;业务专家和开发人员&#xff09;能够通过小程序解决您的关键业务流程挑战。不妨让我们看看在本月的产品与市场发布亮点&#xff0c;看看它们如何帮助您实现目标。 产品方面的相关动向&#x1f447;&#x1f447;&#x1f447; 全新版本的小程序统…

知识图谱实战应用12-食谱领域智能问答系统,实现菜谱问答

大家好,我是微学AI,今天给大家介绍一下知识图谱实战应用12-食谱领域智能问答系统,实现菜谱问答,本项目基于py2neo和neo4j图数据库,将知识图谱应用于菜谱领域。通过构建菜谱知识图谱,实现简单的菜谱食材问答系统。用户可以通过问答系统,快速获取简单的菜谱食材信息。 一…

Vivado综合属性系列之十一 GATED_CLOCK

目录 一、前言 二、GATED_CLOCK 2.1 属性说明 2.2 工程代码 2.3 综合结果 一、前言 在工程设计中&#xff0c;时钟信号通常来源于专用的时钟单元&#xff0c;如MMCM和PLL等。但也存在来自逻辑单元的信号作为时钟&#xff0c;这种时钟信号为门控时钟。门控时钟可以降低时…

Linux下V4l2框架编程_USB摄像头数据采集

Linux内核版本:3.5.0 1.1 V4L2简介 v4L2是针对uvc免驱usb设备的编程框架,主要用于采集usb摄像头等。 这篇文章介绍V4L2框架读取摄像头数据的流程,介绍ioctl常用的命令参数,以及各种摄像头相关的结构体成员含义,最终完成数据采集。 编程模式如下: V4l2支持多种设备,它可…

项目管理PMP好考吗,没有经验?

现在越来越多的产品经理和开发人员也投入到考PMP的大军中&#xff0c;在真实的项目中也会有很多产品经理兼任项目经理的职责&#xff0c;这点还是比较常见的&#xff0c;如果说产品或者开发人员考了PMP证书&#xff0c;本身也会让你在找工作的大军中更具有优势&#xff0c;俗话…