【数据结构和算法】树表的查找算法(二叉排序树与平衡二叉树)

简介: 【数据结构和算法】树表的查找算法(二叉排序树与平衡二叉树)

二叉排序树


1、二叉排序树查的定义

二叉排序树有称为二叉搜索树,二叉查找树


  • 二叉排序树的定义:

image.png

  • 二叉排序树的例子

image.png

  • 二叉排序树性质:中序遍历非空的二叉排序树所得到的数据元素序列是一个按关键字排列的递增有序序列。
  • 二叉排序树结果出现的原因:二叉排序树的左节点的数字比根节点要小,而右节点的数字要比根节点要大。而中序遍历是先左子树,然后再跟,在右子树,所以便得到一个递增的有序序列。


2、二叉排序树查找算法

  • 二叉树的查找

image.png

分析:

 如上例子中,需要进行对105进行查找,首先105比122小,所以查找根节点的左子树99,然后发现99小于105,所以查找左子树的根节点99的右子树110,但110比105大,再查找110根节点的左子树,发现110的左子树就是105,查找成功。

  • 二叉排序树的存储结构
typedef struct{
  KeyType key;  //关键字项
  InfoType otherInfo; //其他数据域
}ElemType;
typedef struct BSTNode{
  ElemType data;  //数据域
  struct BSTNode *lchild,*rchild; //左右孩子指针
}BSTNode,*BSTree;
BSTree T;    //定义二叉排序树T


算法思路

image.png


算法的代码实现

BSTree SearchBST(BSTree T,KeyType key){
  if( !T || key == T->data.key) //如果树为空或者找到了,就返回这个T
  return T;     //为空就返回了NULL,否则返回找到的根节点
  else if(key < T->data.key)  //小于根节点,在左子树中继续查找
  return SearchBST(T->lchild,key);
  else        //大于根节点,在右子树中继续查找
  return SearchBST(T->rchild,key);
}


3、二叉排序树的算法分析

二叉排序树的平均查找长度法分析

image.png


(其中,右边的二叉排序树退化成顺序查找法)

image.png

(含有n个节点的二叉排序树的平均查找长度和树的形态有关)

二叉排序树的改进:针对树的形态会影响时间的复杂度,如何提高形态不均航的二叉排序树的查找效率?


解决方法:做“平衡化”处理,既尽量让二叉树的形状均衡。(也就是平衡二叉树)


4、二叉排序树的插入与生成

二叉排序树的插入思路

image.png

(插入的元素一定在叶节点上)


二叉排序树插入的例子

image.png


分析:

以40为例,首先40与根节点45比较,但是小于根节点,所以进入到根节点的左孩子12,;40比左孩子12大,再进入根节点12的右孩子37,此时40比根节点37大而且根节点没有右孩子,所以40就成为了根节点的右孩子。


二叉排序树插入算法

int InsertBST(BSTree T,KeyType key){
  if( !T) {    //如果树为空,说明应该在此空位插入
  T = (BSTree*)malloc(sizeof(BSTree));  //创建一个节点
  T->data.key = key;  //赋值
  .....     //其他操作
  return 0;
  }
  else if( key == T->data.key)
  return -1;      //等于根节点,啥也不做,结束函数
  else if(key < T->data.key )
  InsertBST(T->lchild,key); //小于根节点,递归查找左子树
  else  
  InsertBST(T->rchild,key); //大于根节点,递归查找又子树
}


二叉排序树的生成:从空树出发,进过一系列的查找,插入操作之后,可生成一棵二叉排序树

image.png

ps:

  1. 一个无序序列可以通过二叉排序树而变成一个有序序列,构造树的过程就是对无序序列进排序的过程。
  2. 插入的结点均为叶子结点,故无需移动其他结点,相当于在有序序列上插入记录而无需移动其他记录。
  3. 关键字的输入顺序的不同,建立的二叉排序树也可能将会不相同。

(二叉树的形态不一样,时间的复杂度也会不一样)

image.png


5、二叉排序树的删除

情况1:被删除的结点是叶子结点,直接删除该结点

删前:

image.png

删后:

image.png


情况2:被删除的结点只有左子树或者是右子树,用其左子树或者是右子树替换它(结点的替换)

删前:

image.png

删后:

image.png


情况3:被删除的结点既有左子树也有右子树

删前:

image.png

找到被删关键字50的前驱节点40,并将其替换掉被删节点:

image.png

再原本的前驱节点40删除(如果40有左子树也有右子树就在同样重复上诉的步骤,再找到一40位跟结点的数中的左子树的前驱节点,再替换便可),而由于此处的40只有左子树,所以用40的左子树替换其便可。也就是30直接指向35。

image.png

再一个例子

image.png

总结–树表的删除有两种方法:找出前驱节点替换,或找出后继节点替换。


平衡二叉树


1、平衡二叉树的定义

平衡二叉树的定义(又称为AVL树)

image.png

平衡二叉树的平衡因子

image.png

平衡二叉树的例子

image.png


2、平衡二叉树的四种调整方法

平衡调整的四种类型

image.png

平衡调整4种类型的方法

image.png

ps:调整的原则为:

降低高度原则

保持二叉排序树的性质(左子树比根节点小,右子树比根节点大)


类型1:LL型

类型1:LL型的调整过程

步骤1:开始:

image.png

步骤二:B结点带着左子树α一起上升

image.png

步骤三:A结点成为B的右孩子,B原来的右子树不要

image.png

步骤四:原来B节点的右子树β作为A的左子树

image.png

示例:

image.png


类型2:RR型

类型2:RR型的调整过程

步骤一:开始

image.png

步骤二:B节点带右子树β一起上升

image.png

步骤三:A节点成为B的左孩子

image.png

步骤四:原来B结点的左子树α作为A的右子树

image.png

示例:

image.png

调整结果:

image.png


类型3:LR型

类型3:LR型的调整过程

步骤一:开始

image.png

步骤二:C结点穿过A,B结点上升

image.png

步骤三:B结点成为C的左孩子,A结点成为C的右孩子

image.png

步骤四:原来C结点的左孩子β作为B的右子树,原来C结点的右孩子γ作为A的左子树

image.png

示例:

image.png


类型4:RL型

类型4:RL型的调整过程

(演示略)示例:

image.png

结果如下:

image.png


3、平衡二叉树的构建

构建一棵平衡二叉树的示例

image.png


构建过程如下所示:

  1. 插入7出现LR类型16,3,7,调整。

image.png

  1. 插入9出现LL类型16,11,9,调整。

image.png

  1. 插入26出现RR型7,11,16,调整。

image.png

  1. 插入18出现RL型16,26,18,调整。

image.png

  1. 插入14,没有失衡

image.png

  1. 插入15出现LR型16,14,15,调整。

image.png

  1. 如此,AVL树构建完成,这是查找性能最好的平衡二叉树


参考链接:https://space.bilibili.com/40323036

目录
相关文章
|
9月前
|
存储 监控 安全
企业上网监控系统中红黑树数据结构的 Python 算法实现与应用研究
企业上网监控系统需高效处理海量数据,传统数据结构存在性能瓶颈。红黑树通过自平衡机制,确保查找、插入、删除操作的时间复杂度稳定在 O(log n),适用于网络记录存储、设备信息维护及安全事件排序等场景。本文分析红黑树的理论基础、应用场景及 Python 实现,并探讨其在企业监控系统中的实践价值,提升系统性能与稳定性。
513 1
|
9月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
231 0
|
存储 算法 Java
算法系列之数据结构-二叉树
树是一种重要的非线性数据结构,广泛应用于各种算法和应用中。本文介绍了树的基本概念、常见类型(如二叉树、满二叉树、完全二叉树、平衡二叉树、B树等)及其在Java中的实现。通过递归方法实现了二叉树的前序、中序、后序和层次遍历,并展示了具体的代码示例和运行结果。掌握树结构有助于提高编程能力,优化算法设计。
398 10
 算法系列之数据结构-二叉树
|
算法 Java
算法系列之数据结构-Huffman树
Huffman树(哈夫曼树)又称最优二叉树,是一种带权路径长度最短的二叉树,常用于信息传输、数据压缩等方面。它的构造基于字符出现的频率,通过将频率较低的字符组合在一起,最终形成一棵树。在Huffman树中,每个叶节点代表一个字符,而每个字符的编码则是从根节点到叶节点的路径所对应的二进制序列。
380 3
 算法系列之数据结构-Huffman树
|
算法 Java
算法系列之数据结构-二叉搜索树
二叉查找树(Binary Search Tree,简称BST)是一种常用的数据结构,它能够高效地进行查找、插入和删除操作。二叉查找树的特点是,对于树中的每个节点,其左子树中的所有节点都小于该节点,而右子树中的所有节点都大于该节点。
539 22
|
存储 机器学习/深度学习 算法
C 408—《数据结构》算法题基础篇—链表(下)
408考研——《数据结构》算法题基础篇之链表(下)。
487 30
|
C语言 C++ 容器
【数据结构】二叉搜索树(二叉排序树)
本文介绍了二叉搜索树(Binary Search Tree, BST)的定义、实现及其性能分析。二叉搜索树是一种特殊的二叉树,其特点是左子树所有节点值小于根节点值,右子树所有节点值大于根节点值,且每个子树也满足此特性。文中详细讲解了BST的节点结构、插入、查找、删除等操作的实现,并通过C++代码展示了这些功能。此外,还讨论了BST的性能:在理想情况下,时间复杂度接近O(logN),但在最坏情况下可能退化为O(N)。为了提高效率,后续将学习自平衡二叉搜索树如AVL树和红黑树。掌握BST有助于理解STL中的set和map容器。感谢阅读,欢迎点赞支持。
1297 9
|
存储 算法 C语言
C 408—《数据结构》算法题基础篇—链表(上)
408考研——《数据结构》算法题基础篇之链表(上)。
712 25
|
存储 人工智能 算法
C 408—《数据结构》算法题基础篇—数组(通俗易懂)
408考研——《数据结构》算法题基础篇之数组。(408算法题的入门)
860 23
|
算法 C++
【C++数据结构——查找】二叉排序树(头歌实践教学平台习题)【合集】
【数据结构——查找】二叉排序树(头歌实践教学平台习题)【合集】 目录 任务描述 相关知识 测试说明 我的通关代码: 测试结果: 任务描述 本关任务:实现二叉排序树的基本算法。 相关知识 为了完成本关任务,你需要掌握:二叉树的创建、查找和删除算法。具体如下: (1)由关键字序列(4,9,0,1,8,6,3,5,2,7)创建一棵二叉排序树bt并以括号表示法输出。 (2)判断bt是否为一棵二叉排序树。 (3)采用递归方法查找关键字为6的结点,并输出其查找路径。 (4)分别删除bt中关键
376 11
【C++数据结构——查找】二叉排序树(头歌实践教学平台习题)【合集】

热门文章

最新文章