数据结构之动态查找表

数据结构之动态查找表

  • 1、二叉排序树
    • 1.1、二排序树的定义
    • 1.2、二叉排序树的查找过程
    • 1.3、在二叉排序树中插入结点的操作
    • 1.4、在二叉排序树中删除结点的操作
  • 2、平衡二叉树
    • 2.1、平衡二叉树上的插入操作
    • 2.2、平衡二叉树上的删除操作
  • 3、B_树

  数据结构是程序设计的重要基础,它所讨论的内容和技术对从事软件项目的开发有重要作用。学习数据结构要达到的目标是学会从问题出发,分析和研究计算机加工的数据的特性,以便为应用所涉及的数据选择适当的逻辑结构、存储结构及其相应的操作方法,为提高利用计算机解决问题的效率服务。
  动态查找表的特点是表结构本身是在查找过程中动态生成的,即对于给定值 key,若表中存在关键字等于 key 的记录,则查找成功返回;否则插入关键字为 key 的记录。

1、二叉排序树

1.1、二排序树的定义

  二叉排序树又称二叉查找树,它或者是一棵空树,或者是具有以下性质的二叉树。
  (1)若它的左子树非空,则左子树上所有结点的值均小于根结点的值。
  (2)若它的右子树非空,则右子树上所有结点的值均大于根结点的值。
  (3)左、右子树本身是二叉排序树。
  下图为一棵二叉排序树。
在这里插入图片描述

1.2、二叉排序树的查找过程

  因为二叉排序树的左子树上所有结点的关键字均小于根结点的关键字,右子树上所有结点的关键字均大于根结点的关键字,所以在二叉排序树上进行查找的过程为: 二叉排序树非空时,将给定值与根结点的关键字值相比较,若相等,则查找成功;若不相等,则当根结点的关键字值大于给定值时,下一步到根的左子树中进行查找,否则到根的右子树中进行查找。若查找成功,则查找过程是走了一条从树根到所找到结点的路径;否则,查找过程终止于一棵空的子树。
  设二叉排序树采用二叉链表存储,结点的类型定义如下:

typedef struct Tnode{int data;						/*结点的关键字值*/struct Tnode *lchild,*rchild;	/*指向左、右子树的指针*/
}BSTnode,*BSTree;

  【函数】二叉排序树的查找算法。

BSTree SearchBST(BSTree root, int key, BSTree *father)
/*在root 指向根的二叉排序树中查找键值为 key 的结点*/
/*若找到,返回该结点的指针;否则返回空指针 NULL*/
{BSTree p = root; *father = NULL;while (p && p->data!=key){*father = p;if( key < p->data ) p = p->lchild;else p = p->rchild;}/*while*/return p;
}/*SearchBST*/

1.3、在二叉排序树中插入结点的操作

  二叉排序树是通过依次输入数据元素并把它们插入到二叉树的适当位置构造起来的,具体的过程是:每读入一个元素,建立一个新结点。若二叉排序树非空,则将新结点的值与根结点的值相比较,如果小于根结点的值,则插入到左子树中,否则插入到右子树中;若二叉排序树为空,则新结点作为二叉排序树的根结点。设关键字序列为{46,25,54,13,29,91},则整个二叉排序树的构造过程如下图 所示。
在这里插入图片描述

  【函数】二叉排序树的插入算法。

int InsertBST(BSTree *root, int newkey)
/*在*root 指向根的二叉排序树中插入一个键值为 newkey 的结点,插入成功则返回0,否则返回-1*/
{BSTree s,p,f;s =(BSTree)malloc(sizeof(BSTnode));if (!s) return -1;s->data = newkey; s->lchild = NULL;s->rchild = NULL;p = SearchBST(*root, newkey, &f);		/*寻找插入位置*/if(p) return -1;						/*键值为 newkey 的结点已在树中,不再插入*/if(!f) *root= s;						/*若为空树,键值为newkey 的结点为树根*/else if (newkey < f->data) 				/*作为父结点的左孩子插入*/f->lchild = s;else f->rchild = s;						/*作为父结点的右孩子插入*/return 0;
}/*InsertBST*/

  从上面的插入过程还可以看到,每次插入的新结点都是二叉排序树上新的叶子结点,因此插入结点时不必移动其他结点,仅需改动某个结点的孩子指针。这就相当于在一个有序序列上插入一个记录而不需要移动其他记录。这表明在二叉排序树进行查找具有类似于折半查找的特性,二叉排序树可采用链表存储结构,因此是动态查找表的一种适宜表示。
  另外,由于一棵二叉排序树的形态完全由输入序列决定,所以在输入序列已经有序的情况下,所构造的二叉排序树是一棵单枝树。例如,对于关键字序列 (12,18,23,45,60),建立的二叉排序树如下图所示,这种情况下的查找效率与顺序查找的效率相同。
在这里插入图片描述

1.4、在二叉排序树中删除结点的操作

  在二叉排序树中删除一个结点,不能把以该结点为根的子树都删除,只能删除这个结点并仍旧保持二叉排序树的特性。也就是说,在二叉排序树上删除一个结点相当于在有序序列中删除一个元素。
  假设要在二叉排序树种删除结点 *p(p 指向被删除结点),*f 为其双亲结点,则该操作可分为3 种情况:结点*p 为叶子结点; 结点*p 只有左子树或者只有右子树;结点*p 的左子树、右子树均存在。
  (1)若结点 *p 为叶子结点且 *p 不是根结点,即 p->lchild 及 p->rchild 均为空,则由于删去叶子结点后不破坏整棵树的结构,因此只需修改 *p 的双亲结点 *f 的相应指针即可。
    f->lchild(或 f->rchild)= NULL;
  若结点 *p 只有左子树或者只有右子树且 *p 不是根结点,此时只要将 *p 的左子树或右子树接成其双亲结点 *f的左子树(或右子树),即令
    f->lchild (或 f->rchild)= p->lchild;
  或
    f>lchild(或 f>rchild) = p->rchild:
  (3)若 *p 结点的左、右子树均不空,则删除 *p 结点时应将其左子树、右子树连接到适当的位置,并保持二叉排序树的特性。可采用以下两种方法进行处理:一是令 *p 的左子树为 *f的左子树(若 *p 不是根结点且 *p 是 *f的左子树,否则为右子树),而将 *p 的右子树下接到中序遍历时 *p 的直接前驱结点 *s ( *s 结点是 *p 的左子树中最右下方的结点) 的右孩子指针上;是用 *p 的中序直接前驱(或后继)结点 *s 代替 *p 结点,然后删除 *s 结点,如下图所示
在这里插入图片描述

  从二叉排序树的定义可知,中序遍历二叉排序树可得到一个关键字有序的序列。这也说明,一个无序序列可以通过构造一棵二叉排序树而得到一个有序序列,构造二叉排序树的过程就是对无序序列进行排序的过程。

2、平衡二叉树

  平衡二叉树又称为 AVL 树,它或者是一棵空树,或者是具有下列性质的二叉树。它的左子树和右子树都是平衡二叉树,且左子树和右子树的高度之差的绝对值不超过 1。若将二叉树结点的平衡因子(Balance Factor,BF) 定义为该结点左子树的高度减去其右子树的高度,则平衡二叉树上所有结点的平衡因子只可能是-1、0 和 1。只要树上有一个结点的平衡因子的绝对值大于1,则该二又树就是不平衡的。
  分析二叉排序树的查找过程可知,只有在树的形态比较均匀的情况下,查找效率才能达到最佳。因此,希望在构造二叉排序树的过程中,保持其为一棵平衡二叉树。
  使二叉排序树保持平衡的基本思想是: 每当在二叉排序树中插入一个结点时,首先检查是否因插入破坏了平衡。若是,则找出其中的最小不平衡二叉树,在保持二叉排序树特性的情况下,调整最小不平衡子树中结点之间的关系,以达到新的平衡。所谓最小不平衡子树,是指离插入结点最近且以平衡因子的绝对值大于1 的结点作为根的子树。

2.1、平衡二叉树上的插入操作

  一般情况下,假设由于在二叉排序树上插入结点而失去平衡的最小子树根结点的指针为a,也就是说,a 所指结点是离插入结点最近且平衡因子的绝对值超过1的祖先结点,那么,失去平衡后进行调整的规律可归纳为以下4种情况。
  (1)LL型单向右旋平衡处理。如下图所示,由于在 *a(即结点A)的左子树的左子树上插入新结点,使 *a 的平衡因子由1增至2,导致以*a 为根的子树失去平衡,因此需进行一次向右的顺时针旋转操作。
在这里插入图片描述

  (2)RR型单向左旋平衡处理。如下图所示,由于在 *a(即结点A)的右子树的右子树上插入新结点,使 *a 的平衡因子由 -1变为 -2,导致以 *a 为根的子树失去平衡,因此需进行一次向左的逆时针旋转操作。
在这里插入图片描述

  (3)LR型先左后右双向旋转平衡处理。如下图所示,由于在 *a(即结点A)的左子树的右子树上插入新结点,使 *a 的平衡因子由 1 增至2,导致以 *a 为根结点的子树失去平衡,因此需进行两次旋转(先左旋后右旋)操作。
在这里插入图片描述

  (4)RL型先右后左双向旋转平衡处理。如下图所示,由于在 *a(即结点A)的右子树的左子树上插入新结点,使 *a的平衡因子由 -1变为 -2,导致以 *a为根结点的子树失去平衡,因此需进行两次旋转(先右旋后左旋)操作。
在这里插入图片描述

2.2、平衡二叉树上的删除操作

  在平衡二叉树上进行删除操作比插入操作更复杂。若待删结点的两个子树都不为空,就用该结点左子树上的中序遍历的最后一个结点(或其右子树上的第一个结点)替换该结点,将情况转化为待删除的结点只有一个子树后再进行处理。当一个结点被删除后,从被删结点到树根的路径上所有结点的平衡因子都需要更新。对于每一个位于该路径上的平衡因子为 ±2 的结点来说,都要进行平衡处理。

3、B_树

  一棵m阶的B_树,或为空树,或为满足下列特性的m叉树。
  (1)树中每个结点最多有m棵子树。
  (2)若根结点不是叶子结点,则最少有两棵子树。
  (3)除根之外的所有非终端结点最少有 m 2 \frac m2 2m棵子树。
  (4)所有的非终端结点中包含下列数据信息
( n , A 0 , K 1 , A 1 , K 2 , A 2 , . . . , K n , A n ) (n,A_0,K_1,A_1,K_2,A_2,...,K_n,A_n) (n,A0,K1,A1,K2,A2,...,Kn,An)
其中,Ki(i=1,2,…,n)为关键字,且Ki<Ki+1(i=1,2,…,n-1); Ai(i=0,1,…,n)为指向子树根结点的指针,且指针 Ai-1 所指子树中所有结点的关键字均小于 Ki(i=1,2,…,n),An所指子树中所有结点的关键字均大于Kn,n 为结点中关键字的个数且满足 { m 2 − 1 ≤ n ≤ m − 1 } {\huge\{}\frac m2 -1≤n≤m-1\huge\} {2m1nm1}
  (5)所有的叶子结点都出现在同一层次上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)。
  一棵4阶的B树如下图所示。
在这里插入图片描述

  由 B树的定义可知,在 B树上进行查找的过程是:首先在根结点所包含的关键字中查找给定的关键字,若找到则成功返回;否则确定待查找的关键字所在的子树并继续进行查找,直到查找虚功或查找失败(指针为空) 时为止。
  B树上的插入和删除运算较为复杂,因为要保证运算后结点中关键字的个数大子等于 m 2 − 1 \frac m2-1 2m1,因此涉及结点的“分裂”及“合并”问题。
  在B树中插入一个关键字时,不是在树中增加一个叶子结点,而是首先在低层的某个非终端结点中添加一个关键字,若该结点中关键字的个数不超过 m-1,则完成插入;否则,要进行结点的“分裂”处理。所谓“分裂”,就是把结点中处于中间位置上的关键字取出来插入到其父结点中,并以该关键字为分界线,把原结点分成两个结点。“分裂”过程可能会一直持续到树根。
  同样,在 B_树中删除一个结点时,首先找到关键字所在的结点,若该结点在含有信息的最后一层,且其中关键字的数目不少于 m 2 − 1 \frac m2-1 2m1,则完成删除;否则需进行结点的“合并”运算。若待删除的关键字所在的结点不在含有信息的最后一层,则将该关键字用其在 B 树中的后继替代,然后删除其后继元素,即将需要处理的情况统一转化为在含有信息的最后一层再进行删除运算。

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

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

相关文章

C++——数据类型

C——数据类型 1.基本变量类型 C 基本数据类型整理成表格。以下是一个表格&#xff0c;展示了不同的基本数据类型及其一般用途和大小范围&#xff1a;和C语言类似。 2.宽字符的用法 #include <iostream> #include <locale> #include <wchar.h> int main…

avast网页随机密码生成器

随机密码生成器 | 告别 12345 | Avast 可以生成随机密码 按需调整

MySQL之谈谈MySQL里的日志

文章目录 前言一、SQL是如何做更新操作的二、MySQL中的redo log三、MySQL中的binlog四、聊聊两阶段提交总结 前言 上一章我们讲了一条SQL是如何做查询的&#xff0c;其中经历了许多步骤。这次来讲讲一条SQL是如何做更新操作的。 常有大佬说他可以把MySQL恢复到半个月内任意一秒…

Android搭建python环境

通过wifi连接adb&#xff1a; 首先下载无线abd工具&#xff1a; https://www.downkuai.com/android/170494.html 运行效果图&#xff1a; 然后开启后根据自身ip即可连接&#xff1a; adb connect ip:5555 安装busybox: 首先执行如下命令查看手机架构&#xff1a; adb sh…

Java的JVM学习一

一、java中的内存结构如何划分 栈和堆的区别&#xff1a; 栈负责处理运行&#xff0c;堆负债处理存储。 区域名称作用虚拟机栈用于存储正在执行的每个Java方法&#xff0c;以及其方法的局部变量表等。局部变量表存放了便器可知长度的各种基本数据类型&#xff0c;对象引用&am…

SpringBoot security 安全认证(二)——登录拦截器

本节内容&#xff1a;实现登录拦截器&#xff0c;除了登录接口之外所有接口访问都要携带Token&#xff0c;并且对Token合法性进行验证&#xff0c;实现登录状态的保持。 核心内容&#xff1a; 1、要实现登录拦截器&#xff0c;从Request请求中获取token&#xff0c;从缓存中获…

小程序:类型三级分类

一、效果图片 二、代码 <template><view class"customPosition"><!-- header --><navBar :border"false" :hasBack"true" :title"titleName"></navBar><!-- 查询 --><view class"search…

ChatGPT提示“Unauthorized“错误

问题&#xff1a;当出现下图错误时我们应该如何解决&#xff1f; 解决办法一、 退出重新登录 原因&#xff1a;没有正确登录或者登录会话已经过期 解决办法二、 “更换线路” 原因&#xff1a;网络配置或者代理设置会导致认证失败 如果还不行可以叫我看一下 无限使用gpt4教…

手把手教你搭建属于自己的网站(获取被动收入),无需服务器,使用github托管

大家好&#xff0c;我是亚洲著名程序员青松&#xff0c;本次教大家如何搭建一个属于自己的网站。 下面是我自己搭建的一个网站&#xff0c;是一个网址导航网站。托管在了github上面&#xff0c;目前已经运营了三个月&#xff0c;每天的访问量大约有100ip左右。 下图是在51.la上…

猫用空气净化器好吗?好用的养猫宠物空气净化器品牌推荐

作为一个养猫五年的资深铲屎官&#xff0c;我对如何轻松快乐地养猫有一些心得。猫咪每天在家里奔跑&#xff0c;导致家里经常会出现“猫毛雪”&#xff0c;沙发、地板和衣服都成了重灾区。在除猫毛的问题上&#xff0c;我真的尝试了各种方法&#xff0c;几乎用上了所有的技能。…

简单说说-docker网络类型

概述 容器网络是指容器之间或非 Docker 工作负载之间连接和通信的能力。容器默认启用网络&#xff0c;并且可以建立传出连接。容器不知道它所连接的网络类型&#xff0c;容器只能看到带有 IP 地址、网关、路由表、DNS 服务和其他网络详细信息的网络接口。也就是说&#xff0c;…

怎么去除图片中不需要的部分?这三种高效方法快来试一下

在数字图像处理的浩瀚世界中&#xff0c;去除图片中不必要部分的任务&#xff0c;宛如一幅细致的画卷&#xff0c;需精心描绘。这些不必要部分&#xff0c;可能是背景、水印、无关紧要物体或错误部分&#xff0c;它们如同图片中的瑕疵&#xff0c;需要被巧妙地修饰或去除。这不…

09. 配置Eth-Trunk

文章目录 一. 初识Eth-Trunk1.1. Eth-Trunk的概述1.2. Eth-Trunk的优势1.3. Eth-Trunk的模式的优势 二. 实验专题2.1. 实验1&#xff1a;手工模式2.1.1. 实验拓扑图2.1.2. 实验步骤&#xff08;1&#xff09;配置PC机的IP地址&#xff08;2&#xff09;在交换机接口划入VLAN&am…

【Tomcat与网络11】如何自己实现一个简单的HTTP服务器

在前面我们尝试解释Tomcat的理论&#xff0c;但是呢&#xff0c;很多时候那些复杂的架构和设计会让我们眼花缭乱&#xff0c;以至于忽略了最进本的问题——服务器到底是什么&#xff1f;今天我们就用尽量简单的代码实现一个简易的HTTP服务器。 HTTP启动之后要持续监听&#xf…

校园网网络规划与设计——计算机网络实践报告

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; 目录 一、设计目的 二、软硬件环境 三、理论基础 四、设计方案 五、网络配置步骤 六、设计过程中出现的问题及相应解决办法 八、参考资料 一、设计目的 深入理解网络工程的三层层次设计模型&#xff1b; 掌握网络…

2024年美赛数学建模A题思路分析 - 资源可用性和性别比例

# 1 赛题 问题A&#xff1a;资源可用性和性别比例 虽然一些动物物种存在于通常的雄性或雌性性别之外&#xff0c;但大多数物种实质上是雄性或雌性。虽然许多物种在出生时的性别比例为1&#xff1a;1&#xff0c;但其他物种的性别比例并不均匀。这被称为适应性性别比例的变化。…

【Java】阻塞队列

目录 BlockingQueue BlockingQueue接口 三个主要实现类介绍&#xff1a; ArrayBlockingQueue&#xff1a;有界队列 LinkedBlockingQueue&#xff1a;无界队列 SynchronousQueue:同步队列 队列对比 BlockingQueue 对于Queue而言&#xff0c;BlockingQueue是主要的线程安全…

有深浅入数据分析 - 启发法(凭人类的天性做分析)

在做数据分析的时候&#xff0c;往往最优的方法是艰难耗时间的 凭经验处理&#xff0c;迅速做出决策&#xff0c;确识能够奏效&#xff0c;进行数据分析的重要而必要的技能 领导的要求是&#xff1a; 邋遢集的处理方式是&#xff1a; 计量的方式处理 上图的调查问卷可以…

Axure 动态面板初使用-实现简单的tab切换页面效果

使用工具版本 Axure 9 实现的效果 步骤过程 1、打开Axure 9&#xff0c;默认进入一个空白页&#xff0c;首先从元件库拉一个动态面板到页面中&#xff0c;位置肯定是C位咯~ 2、将面板尺寸调整一下&#xff0c;设置成你喜欢的数字&#xff0c;比如我就喜欢800600 3、然后…

学习日志以及个人总结(13) 指针!

指针 定义 访问内存地址 操控硬件 指针&#xff1a; 指针基本数据据类 指针数组 指针函数 指针指针 1.指针&#xff1a;就是地址-----就是内存的单元的编号 2.指针变量 语法&#xff1a; 基类型* 指针变量名&#xff1b; 基类型-------数据类型//基础数据类型 //数组…