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

这篇具有很好参考价值的文章主要介绍了数据结构与算法:树形查找。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一.二叉排序树(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. 如果删除的是根节点,则需要将新的根节点返回。

原理图:

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

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

二.平衡二叉树(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. 每个红色节点必须有两个黑色子节点。

颜色调整包括三种情况:

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

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

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

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

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

四.B树(多路平衡查找树)

1.定义与性质

B树,又称多路平衡查找树,B树中所有结点的孩子个数的最大值称为B树的阶,通常用m表示。一棵m阶B树或为空树,或为满足如下特性的m叉树:

  • 1)树中每个结点至多有m棵子树,即至多含有m-1个关键字。
  • 2)若根结点不是终端结点,则至少有两棵子树。
  • 3)除根结点外的所有非叶结点至少有[m/2]棵子树,即至少含有[m/21-1个关键字。
  • 5)所有的叶结点都出现在同-层次上,并且不带信息(可以视为外部结点或类似于折半查找判定树的查找失败结点,实际上这些结点不存在,指向这些结点的指针为空)

2.B树高度

B树的高度取决于它的节点数和每个节点所能容纳的关键字数量。B树通常被描述为一棵平衡树,因为它会在插入或删除元素时自动调整其结构,以保持树的平衡。

对于一棵B树来说,它的根节点到最深叶子节点的路径长度就是这棵树的高度。由于B树的每个节点都可以包含多个关键字,因此它比二叉搜索树更加紧密,这意味着它的高度要低得多。具体而言,如果一个B树的节点最多可以包含k个关键字,那么它的高度不会超过logk(n+1),其中n是这棵树中关键字的总数。

因此,B树通常可以在O(log n)时间内查找、插入和删除关键字,即使当数据量非常大时也能够保持高效。

3.插入与删除

B树的插入操作大致分为以下几个步骤:

  1. 首先,我们需要先在B树中找到要插入新关键字的位置,这个过程类似于查找操作。
  2. 如果找到了对应的叶子节点,就直接将新关键字插入到叶子节点中;
  3. 如果叶子节点已满,那么我们需要先进行节点分裂操作,将该节点分成两个节点,并调整父节点指向这两个节点的链接;
  4. 重复执行上述过程,直到插入新关键字成功。

B树的删除操作也比较复杂,大致分为以下几个步骤:

  1. 在B树中查找待删除的关键字,如果找不到则直接返回;
  2. 如果待删除的关键字所在的节点不是叶子节点,则需要用该节点的前驱或后继关键字代替待删除关键字,并将前驱或后继关键字删除;
  3. 如果待删除的关键字所在节点是叶子节点,则直接删除该关键字;
  4. 如果删除操作导致某个节点的关键字数量小于最小值,则需要进行节点合并操作,将该节点与其兄弟节点合并,并调整父节点指向这两个节点的链接;
  5. 重复执行上述步骤,直到删除操作完成。

需要注意的是,在B树中,为了保证平衡性,插入和删除操作都可能导致节点分裂或合并,从而改变B树的结构。因此,B树的插入和删除操作相对于普通的二叉搜索树来说更加复杂。

五.B+树

B+树是一种基于B树的数据结构,与B树相比,在存储大量数据时具有更好的性能和空间利用率。

B+树和B树的区别主要在于:

  1. B+树中的非叶子节点不保存关键字对应的值,只保存关键字和指向子节点的指针;
  2. 所有的关键字都保存在叶子节点中,且叶子节点之间按照顺序连接形成一个链表;
  3. 叶子节点中的每个关键字都会连同其对应的值一起被保存;
  4. 叶子节点的指针指向记录的真实存储地址。

B+树的优点在于:

  1. 因为所有的关键字都保存在叶子节点中,所以遍历所有的关键字时无需进行多余的非叶子节点的遍历,这大大减少了I/O操作次数,提高了查找效率;
  2. 叶子节点之间形成的链表可以进一步提高范围查询的效率;
  3. 非叶子节点占用的空间比较小,因为它们只需要保存关键字和指向子节点的指针,而不需要保存对应的值。

总体来说,B+树适用于对于大规模数据的读取,能够提供更快的查询速度和更好的空间利用率,因此在大多数应用场景中,B+树是比B树更好的选择。
数据结构与算法:树形查找

六.比较分析

1.时间复杂度

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

2.个人理解

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

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

说明:新星计划:数据结构与算法,@西安第一深情,创作打卡3!文章来源地址https://www.toymoban.com/news/detail-462047.html

到了这里,关于数据结构与算法:树形查找的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构07:查找[C++][平衡二叉排序树AVL]

    图源:文心一言 考研笔记整理1w+字,小白友好、代码可跑,请小伙伴放心食用~~🥝🥝 第1版:查资料、写BUG、画导图、画配图~🧩🧩 参考用书: 王道考研《2024年 数据结构考研复习指导》 参考用书配套视频: 7.3_2 平衡二叉树_哔哩哔哩_bilibili 特别感谢:  Chat GPT老师、文心

    2024年02月11日
    浏览(37)
  • 数据结构07:查找[C++][朴素二叉排序树BST]

    图源:文心一言 考研笔记整理 8k+ 字,小白友好、代码可跑,请小伙伴放心食用~~🥝🥝 第1版:查资料、写BUG、画导图、画配图~🧩🧩 参考用书: 王道考研《2024年 数据结构考研复习指导》 参考用书配套视频: 7.3_1 二叉排序树_哔哩哔哩_bilibili 特别感谢:  Chat GPT老师、文心

    2024年02月10日
    浏览(29)
  • 二叉排序树的插入删除和查找(数据结构实训)(难度系数100)

    二叉排序树的插入删除和查找 pre: 前序遍历 in: 中序遍历 post:后序遍历 insert: 插入,本题中不会出现相同的元素 delete: 删除,删除成功输出TRUE,没有该元素则输出FALSE,删除的方法是如果有左子树,以左子树中最大值作为新的树根,否则,以右子树最小值作为树根。 search:

    2024年01月25日
    浏览(36)
  • 数据结构与算法(三):树论(树形结构、二叉树、二叉搜索树、红黑树、Btree&B+Tree、赫夫曼树、堆树)

    树论(树形结构、二叉树、二叉搜索树、红黑树、Btree、B+Tree、赫夫曼树、堆树) 在树形结构里面重要的术语: 结点:树里面的元素。 父子关系:结点之间相连的边 子树:当结点大于1时,其余的结点分为的互不相交的集合称为子树 度:一个结点拥有的子树数量称为结点的

    2024年02月01日
    浏览(81)
  • C语言数据结构二叉排序树的建立、插入、删除、查找操作(原理+完整代码)

    1、若左子树不为空,左子树上所有节点值小于 它根节点的值 2、若右子树不为空,右子树上所有节点值大于 它根节点的值 3、每个节点的左右子树也是二叉排序树 目的:提高查找、插入、删除的速度(不是为了排序) 时间复杂度:由于查找性能取决于树的形态,所以

    2024年02月09日
    浏览(38)
  • 数据结构实验报告(四)——查找和排序算法

    1. 掌握顺序查找技术和拆半查找技术以及部分排序算法的设计思想; 2. 掌握查找、部分排序算法的实现与执行过程。 查找算法 1.顺序查找: 从数组第一个元素开始逐个比较,找到后返回相应下标。 2.折半查找: 从数组中间开始比较,如果需查找值比中间值大,则在中间值右

    2024年02月07日
    浏览(30)
  • 【算法与数据结构】Java实现查找与排序

    也叫做折半查找,属于有序查找算法。 前提条件 :数组数据必须有序,从小到大,或者从大到小都是可以的。 如果是无序的,也可以先进行排序。 但是排序之后,会改变原有数据的顺序,查找出来元素位置跟原来的元素可能是不一样的,所以排序之后再查找只能判断当前数

    2024年01月19日
    浏览(38)
  • 【数据结构】【算法】二叉树、二叉排序树、树的相关操作

    树结构是以分支关系定义的一种层次结构,应用树结构组织起来的数据,逻辑上都具有明显的层次关系。 操作系统中的文件管理系统、网络系统中的域名管理、数据库系统中的索引管理等都使用了树结构来组织和管理数据。 树 Tree 是由n个节点组成的有限集合。在任意一颗非

    2024年02月04日
    浏览(40)
  • c语言数据结构——树形结构之树和二叉树

    二叉树有什么用? 二叉树应用非常广泛。 在操作系统源程序中,树和森林被用来构造文件系统。我们看到的window和linux等文件管理系统都是树型结构。在编译系统中,如C编译器源代码中,二叉树的中序遍历形式被用来存放C 语言中的表达式。其次二叉树本身的应用也非常多,

    2023年04月18日
    浏览(33)
  • 探索树形数据结构,通识树、森林与二叉树的基础知识(专有名词),进一步利用顺序表和链表表示、遍历和线索树形结构

      结点之间有分支,具有层次关系 树的定义 : 树 (tree)是n(n≥0)个有限集。 若n = 0,则称为空树; 若n 0,则它满足如下两个条件: 有且仅有一个特定的称为根(Root)的结点; 其余结点可分为m(m≥0)个互不相交的有限集T1,T2,T3,.....,Tm,其中每一个集合本身又是一棵树,并称为根的

    2024年02月01日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包