数据结构08查找

第九章 查找

另一种在实际应用中大量使用的数据结构--查找表。

所谓查找,即为在一个含有众多的数据元素的查找表中找出某个“特定的”数据元素。

 

查找表 search table 是由同一类型的数据元素构成的集合。集合中的数据元素之间存在着完全松散的关系,故查找表非常灵便。

 

对查找表经常进行的操作:

>查询某个元素是否在查找表中;

>检索某个元素的各种属性;

>插入

>删除

 

静态查找表 static search table:只包含查询和检索。

动态查找表 dynamic search table:包含查询、检索、插入、删除。

 

关键字 Key 用于标识数据元素。

>主关键字 primary key:唯一的标识一个记录。

>次关键字 secondary key:识别若干记录。

 

查找 searching:

根据给定的某个值,在查找表中确定一个其关键字等于给定值的记录。

 

由于表中数据元素之间仅存在“同属一个集合”的松散关系,需在数据元素之间人为的加上一些关系,以便按某种规则进行查找,即以另一种数据结构来表示查找表。

>静态查找表

>动态查找表

 

9.1 静态查找表

静态查找表有不同的表示方法,在不同的表示方法中,实现查找操作的方法也不同。

 

9.1.1 顺序表的查找

以顺序表或线性链表表示静态查找表,则可用顺序查找来实现。

顺序查找 sequential search

从表中最后一个记录开始,逐个进行记录关键字和给定值的比较,若相等,则查找成功;反之,直到第一个记录都不相等,则表明表中没有要查找的记录,查找不成功。

 

Tip:在查找尾端设置哨兵,而免去每一步都要检测整个表是否查找完毕,可节约一半的时间。哨兵的值等于所查找的关键字。

 

查找表性能度量:平均查找长度(Average Search Length)ASL

 


对记录的查找概率不相等的查找表,若能预先得知每个记录的查找概率,则应先对记录的查找概率进行排序,使表中记录按查找概率由小到大重新排列,以便提高查找效率。

在一般情况下,记录的查找概率预先无法测定。

为了提高查找效率,可以在每个记录中附设一个访问频度域,并使顺序表中的记录保持按访问频度非递减有序排列,使得查找概率大的记录在查找过程中不断后移,以便在以后的逐次查找中减少比较次数。

或者在每次查找之后都将刚查找到的记录直接移至表尾。

 

顺序查找:

缺点:平均查找长度较长,当n很大时,查找效率低。

优点:简单且适应面广,对表结构无任何要求,无论记录是否按关键字有序均可应用。

 

 

 

9.1.2 有序表的查找

 

折半查找 binary search:

先确定待查记录所在的范围(区间),然后逐步缩小范围直到找到或找不到该记录为止。

 

折半查找性能:

对任意的n,当n>50时,有下列近似结果

 

折半查找只适用于有序表,且限于顺序存储结构,对线性链表无法有效地进行折半查找。

 

 

Fibonacci查找:

根据Fibonacci序列的特点对表进行分割。

开始时,表中记录个数比某个Fibonacci数小1,即

 

Fibonacci查找的平均性能比折半查找好,但最坏情况下的性能(虽然仍是O(logn))比折半查找差。

另一个优点,分割时只需进行加减运算。

 

插值查找:

根据给定值key来确定进行比较的关键字位置i的查找方案。

公式:

 

其中,high和low为最大关键字和最小关键字的下标。

插值查找只适合于关键字均匀分布的表。在这种情况下,对表长较大的顺序表,其平均性能比折半查找好。

 

9.1.3 静态树表的查找

当有序表中各记录的查找概率不等时,折半查找性能未必最优。

描述查找过程的判定树为何类二叉树时,其查找性能最佳?

如果只考虑查找成功的情况,则查找性能最佳的判定树是其带权内路径长度之和PH值取最小值的二叉树。

称PH值最小的二叉树为静态最优查找树(Static Optimal Search Tree)。

构造静态最优查找树花费的时间代价高。

 

静态树表是把有序的静态查找表根据数据被查找的概率生成一棵二叉树。

 

介绍一种构造近似最优查找树的有效算法。

次优查找树(Nearly Optimal Search Tree):带权内路径长度PH值在所有具有同样权值的二叉树中近似为最小。

方法:选取第i个记录作为根结点,然后分别对左右序列构造两个次优查找树作为i的左右子树。

i满足的条件:左序列权值和右序列权值之和差值的绝对值最小。

 

由于在构造次优查找树的过程中,没有考察单个关键字的相应权值,则有可能出现被选为根的关键字的权值比与它相邻的关键字的权值小。此时应作适当调整:选取邻近的权值较大的关键字作次优查找树的根结点。

例:关键字 A  B   C  D  E

    权值   1  30  2  29  3

大量的实验研究表明,次优查找树和最优查找树的查找性能之差仅为1%~2%,很少超过3%。

且构造次优查找树的算法的时间复杂度为O(nlogn)。

 

 

9.1.4 索引顺序表

有点像Skip List。

分块查找又称索引顺序查找,这是顺序查找的一种改进方法。

除表本身外,还需建立一个“索引表”。

索引表按关键字有序,表或者有序或者分块有序。

分块查找过程需分两步进行:先确定待查记录所在的块(子表),然后在块中顺序查找。

 

由于索引表按关键字有序,则确定块的查找可以用顺序查找,亦可用折半查找。而块中记录是任意排列的,则在块中只能是顺序查找。

分块查找是顺序查找和折半查找的简单结合。

若都用顺序,

 

9.2 动态查找表

表结构支持插入和删除操作。

9.2.1 二叉排序树和平衡二叉树

二叉排序树(Binary Sort Tree)或者是一棵空树,或者是具有下列性质的二叉树:

(1)若左子树不空,则左子树上所有结点均小于根结点;

(2)若右子树不空,则右子树上所有结点均大于根结点;

(3)左右子树均为二叉排序树。

 

 

二叉排序树又称二叉查找树。

中序遍历二叉排序树可得到一个关键字的有序序列。

即一个无序序列可以通过构造一棵二叉排序树而变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。

 

插入:每次插入的新结点都是二叉排序树上新的叶子结点。

删除:  

  1. 若删除点无孩子结点,直接删除;
  2. 若删除点只有一个孩子,则将其孩子替代其位置;
  3. 若删除点有两个孩子,两种方法:
    a) 链上左孩子,右孩子为左孩子的最右;或链上右孩子,左孩子为右孩子最左;
    b) 用直接前驱替代,然后删掉直接前驱;或用直接后继替代,然后删掉直接后继。

 

 

平衡二叉树(Balanced Binary Tree 或 Height-Balanced Tree)或者是一棵空树,或者是具有如下性质的二叉树:

它的左右子树都是平衡二叉树,且左右子树的深度之差的绝对值不超过1。

 

平衡因子BF(Balance Factor):该结点左子树的深度减去右子树的深度。

平衡二叉树所有结点的平衡因子只可能是-1,0,1。

只要二叉树上有一个结点平衡因子的绝对值大于1,则该二叉树就是不平衡的。

 

在平衡二叉排序树BBST上插入一个新的数据元素e的递归算法如下:

  1. 若BBST为空树,则插入一个数据元素为e的新结点作为BBST的根结点,树的深度增1;
  2. 若e的关键字和BBST的根结点的关键字相等,则不进行插入;
  3. 若e的关键字小于BBST的根结点的关键字,而且在BBST的左子树中不存在和e有相同关键字的结点,则将e插入在BBST的左子树上,并且当插入之后的左子树深度加1时,分别就下列不同情况处理之:

    a) BBST的根结点的平衡因子为-1,则将根结点的平衡因子更改为0,BBST的深度不变; 
    b) BBST的根结点的平衡因子为0,则将根结点的平衡因子更改为1,BBST的深度增1;
    c) BBST的根结点的平衡因子为1:
            若BBST的左子树根结点的平衡因子为1,则需进行单向右旋平衡处理,并且在右旋处理之后,将根结点和其右子树根结点的平衡因子更改为0,树的深度不变;
            若BBST的左子树根结点的平衡因子为-1,则需进行先向左、后向右的双向旋转平衡处理,并且在旋转处理之后,修改根结点和其左右子树根结点的平衡因子,树的深度不变;
     
  4. 若e的关键字大于BBST的根结点的关键字,而且在BBST的右子树中不存在和e有相同关键字的结点,则将e插入在BBST的右子树上,并且当插入之后的右子树深度增加1时,分别就不同情况处理之。其处理操作和步骤3中所述相对称。

  

LL型:新结点Y插入到A的左子树的左子树上   左左->右

 

RR型:新结点Y插入到A的右子树的右子树上   右右->左

 

LR型:新结点Y插入到A的左子树的右子树上   左右->左右

                        

 

RL型:新结点Y插入到A的右子树的左子树上   右左->右左

 

                             

AVL树的平衡化处理:通过调换根结点,使左右子树的深度相等。
在一棵AVL树上插入结点可能会破坏树的平衡性,需要平衡化处理恢复平衡,且保持BST的结构性质。

若用Y表示新插入的结点,A表示离新插入结点Y最近的,且平衡因子变为2的祖先结点。

可用4种旋转进行平衡化处理:

>LL型:新结点Y插入到A的左子树的左子树上   左左->右

>RR型:新结点Y插入到A的右子树的右子树上   右右->左

>LR型:新结点Y插入到A的左子树的右子树上   左右->左右

>RL型:新结点Y插入到A的右子树的左子树上   右左->右左

 

4种不平衡情况经调整都有如下特性:

  1. 成为A型,调整前的中值结点成为新的根结点,其平衡因子为0,其左、右孩子分别是小值、大值结点;
  2. 调整后,树的深度和插入结点前一样。

特性2说明,如果插入一个结点导致平衡二叉树失衡,则只需在通向根结点的路径上进行一次平衡调整。

 

 

9.2.2 B-树和B+树

磁盘查找

 

 

 

高为h的B-树的最大结点数:

 

 

设m阶B-树的高为h,失败结点位于h+1层,则关键字个数N最少到达多少?

11结点

22结点

3结点

h结点

若树中关键字有N个,则失败结点数为N+1。

即:

给定m和N可以求出最大高度:m=199,N=1,999,999,可得h<=4;

给定m和h可以求出最少关键字数:m=3,h=4,N>=15。

 

m的选择:查找关键字所用时间最少。

两部分时间:从磁盘读入结点所需时间,在结点中查找关键字所需时间。

在B-树上进行查找的过程是一个顺指针查找结点在结点的关键字中进行查找交叉进行的过程。

 

 

在含有N个关键字的B-树上进行查找时,从根节点到关键字所在结点的路径上涉及的结点数不超过

 

插入过程为自底向上分裂结点。

每次插入首先在最低层的某个非终端结点中添加一个关键字,如果该结点的关键字个数不超过m-1,则插入完成;否则分裂。

B树索引,关键字后跟的是文件地址信息。

 

删除,若不是最后一层非终端结点,则将其用左子树的最右或者右子树的最左来替换。然后删除用于替换的结点。

否则分4种情况:

1、最后一层非终端结点,且为根结点,直接删;

2、最后一层非终端结点,不为根结点。

 

B-树主要用作文件的索引,因此它的查找涉及外存的存取。

查找包括两步:1、在B-树中找结点(磁盘);2、在结点中找关键字(内存)。

即,在磁盘上找到结点后,将其读入内存,再在内存中进行关键字的查找。

 

 

 

B+树:B-树的一种变形。

差异:

1、含k个关键字的结点必有k个子树;

2、非终端结点仅具有索引作用,与记录有关的信息均存放在叶结点中;

3、叶结点依关键字自小而大顺序链接。

 

两个头指针:一个指向根结点,另一个指向关键字最小的叶子结点。

两种查找方式

1、沿着根结点随机查找;

2、从最小关键字结点顺序查找。

 

9.2.3 键树

键树又称数字查找树(Digital Search Tree):

它是一棵度大于等于2的树,树中的每个结点只含有组成关键字的符号。

若关键字是数值,则结点中只包含一个数位;若关键字是单词,则结点中只包含一个字母字符。

 

两种存储方式:1、孩子兄弟链;2、多重链表。

 

9.3 哈希表

9.3.1 什么是哈希表

前述查找结构中,关键字和相对存储位置是随机的,在查找过程中需要进行比较,是建立在比较基础上。

冲突(collision):哈希值相同。

同义词(synonym):哈希值冲突的关键字。

一般情况下,冲突只能尽可能减少,而不能完全避免。

 

哈希表:根据设定的哈希函数H(key)和处理冲突的方法将一组关键字映像到一个有限的连续的地址集(区间)上,并以关键字在地址集中的像作为记录在表中的存储位置,这种表便称为哈希表

这一映像过程称为散列,所得存储位置称为哈希地址散列地址

 

9.3.2 哈希函数的构造方法

好的哈希函数:对于关键字集合,经哈希函数映像到地址集合中任何一个地址的概率是相等的,则称此类哈希函数为均匀的(Uniform)哈希函数

即使关键字经过哈希函数得到一个“随机的地址”,以便使一组关键字的哈希地址均匀分布在整个地址区间中,从而减少冲突。

1、直接定址法

取关键字或关键字的某个线性函数值为哈希地址:

 

2、除留余数法

 

9.3.3 处理冲突的方法

1、开放定址法

 

2、再哈希法

对冲突的关键字用另一个哈希函数计算地址,直至不再冲突。

 

3、链地址法

 

4、建立一个公共溢出区

将冲突的关键字全部加入这个缓冲区中。

 

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

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

相关文章

下载Centos7 64位镜像

下载Centos7 64位镜像 1.打开Centos官网 打开Centos官方网站地址&#xff1a;https://www.centos.org/&#xff0c;点击Get CentOS Now 2.点击Minimal ISO镜像 Minimal ISO镜像&#xff0c;与DVD ISO镜像的差别有很多&#xff0c;这里只说两点 1.Minimal ISO类似于Windows的纯净…

[Objective-C语言教程]结构体(17)

Objective-C数组可定义包含多个相同类型的数据项的变量类型&#xff0c;但结构体是Objective-C编程中的另一个用户定义数据类型&#xff0c;它可组合不同类型的数据项。 结构体用于表示记录&#xff0c;假设要图书馆中跟踪书籍信息。可能希望跟踪每本书的以下属性 - 标题作者学…

Scala01入门

第1章 可伸展的语言 Scala应用范围广&#xff0c;从编写脚本&#xff0c;到建立大型系统。 运行在标准Java平台上&#xff0c;与Java库无缝交互。 更能发挥力量的地方&#xff1a;建立大型系统或可重用控件的架构。 将面向对象和函数式编程加入到静态类型语言。 在Scala中&a…

架构师之路17年精选80篇

【架构必备】 《互联网架构如何实现“高并发”》4W 《TCP接入层的负载均衡、高可用、扩展性架构设计》2.2W 《配置中心架构设计演进》1.7W 《跨公网调用的大坑与架构优化》1.4W 《DNS在架构设计中的巧用》1.9W 《消息如何在网络上安全传输》1.2W 《10W定时任务&#xff0c;如何…

iphone手机型号获取

#import <sys/utsname.h> //手机型号 NSString *device [self iphoneType]; (NSString *)iphoneType { struct utsname systemInfo; uname(&systemInfo); NSString *platform [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; if…

Java网络01基本网络概念

协议 Protocol&#xff1a;明确规则 &#xff08;1&#xff09;地址格式&#xff1b; &#xff08;2&#xff09;数据如何分包&#xff1b; ... TCP/IP四层模型&#xff1a; 应用层 HTTP SMTP POP IMAP 传输层 TCP UDP 网际层 IP 主机网络层 host to host layer 数模、…

apache的产品分类说明

分类 项目名 说明 开发语言 服务器&#xff08;共20&#xff09; Apache HTTP Server全球第一HTTP服务器C/CTomcatJava的Web服务器JavaJames邮件服务器JavaSpamAssassin反垃圾邮件C/CPerlApache的Perl编程语言支持C/CTclTCL脚本语言C/CDirectory Server超级目录服务器JavaAxisW…

Java网络02基本Web概念

URI Uniform Resource Identifier 同一资源标识符 以特定语法标识一个资源的字符串 绝对URI&#xff1a;URI模式模式特有部分 scheme:scheme-specific-part scheme分为&#xff1a; data file本地文件系统 ftp http telnet urn 统一资源名 scheme-specific-part为&am…

解决自建ca认证后浏览器警告

前一篇讲解了基本的建立证书的过程&#xff0c;但是建立后总是会在浏览器那里警告&#xff1a; 此链接不是私密链接 --谷歌浏览器 此证书颁发机构不可信 此证书不是这个网站的 --ie浏览器 总之证书是生成成功了&#xff0c;但是其中的内容填写错误了&a…

设计模式学习(三)——单例模式

在Java开发过程中&#xff0c;很多场景下都会碰到或要用到单例模式&#xff0c;在设计模式里也是经常作为指导学习的热门模式之一&#xff0c;相信每位开发童鞋都用到过。我们总是沿着前辈的足迹去做设定好的思路&#xff0c;往往没去探究为何这么做&#xff0c;所以这篇文章对…

Java网络03流

网络程序所做的很大一部分工作只是输入和输出&#xff1a;从一个系统向另一个系统移动数据。 输出流 Java的基本输出流类是java.io.OutputStream: public abstract class OutputStream 这个类提供了写入数据所需的基本方法&#xff0c;包括&#xff1a; public abstract vo…

基于微信小程序开发的仿微信demo

(本文参考自github/liujians,地址:https://github.com/liujians/weApp) 作者声明&#xff1a; 基于微信小程序开发的仿微信demo 整合了ionic的样式库和weui的样式库 使用请查看使用必读! 更新日志请点击这里 目前功能 查看消息 网络请求获取数据&#xff08;download示例server…

设计模式之六大原则

设计模式之设计原则 这软件设计过程中&#xff0c;有六大设计原则&#xff1a; 单一职责原则里氏替换原则依赖倒置原则接口隔离原则迪米特法则开闭原则由于软件开发过程中&#xff0c;根据业务不同等因素形成了各种复杂的而不可预料的需求&#xff0c;遵守原则&#xff0c;让项…

安装配置tengine

安装tengine 1、依赖gcc openssl-devel pcre-devel zlib-devel 安装&#xff1a;yum install gcc openssl-devel pcre-devel zlib-devel 2、解压tengine压缩包&#xff0c;并进入目录&#xff1b; 3、./configure --prefix/usr/tengine 4、make && make install 5…

使用springboot集成jseesite

请访问 开源中国下的https://git.oschina.net/wolfking/wolfking-jeesitehttps://www.oschina.net/p/wolfking-jeesite?fromerr6Iie3qZt 下载源码&#xff0c;按照如下的运行使用 springboot 改造 jeesite&#xff0c;只保留最简单的系统配置 。 介绍 1、运行主类&#xff0c;…

解决idea 中web项目无法正常显示的问题

转载于:https://www.cnblogs.com/nulijiushimeili/p/10575364.html

Hadoop小知识点

hdfs命令行 上传 hadoop fs -put 文件名 hdfs://主机名:9000/... 下载 hadoop fs -get hdfs://主机名:9000/... 文件名 /hadoop/share/hadoop/mapreduce 文件夹下有测试程序 提交MapReduce任务命令 #hadoop jar hadoop-mapreduce-examples-2.4.1.jar pi 5 5 hadoop fs -m…

copy 扩展名 包含子文件夹 文件 到某个 文件夹

比如我在d:\fff下面有很多子文件夹&#xff0c;子文件夹里还有子文件夹&#xff0c;里面有些文件夹里有.ppm.bz2的后缀的文件&#xff0c;需要把他们找出来复制到d:\fff2里面&#xff0c;应该怎么用批处理写&#xff1f;最佳答案1234echo offfor /r d:\fff %%a in (*.ppm.bz2) …

在线视频常见加密方式及安全性透析

信息化时代&#xff0c;多媒体的应用日渐成为人们生活中不可或缺的部分&#xff0c;无论是获取最新资讯还是教育学习&#xff0c;视频都是直观高效的媒介之一。 基于互联网的快速传播&#xff0c;众多培训机构也逐渐将线下原创版权课程迁移到在线平台中&#xff0c;一方面可以更…

分享一个前后端分离的web项目(vue+spring boot)

Github地址&#xff1a;https://github.com/smallsnail-wh 前端项目名为wh-web后端项目名为wh-server项目展示地址为我的github pages&#xff08;https://smallsnail-wh.github.io&#xff09;用户名&#xff1a;admin&#xff0c;密码admin&#xff08;第一次启动会比较慢&am…