数据结构查找方法及原理.docx

上传人:b****5 文档编号:6607111 上传时间:2023-01-08 格式:DOCX 页数:8 大小:76.28KB
下载 相关 举报
数据结构查找方法及原理.docx_第1页
第1页 / 共8页
数据结构查找方法及原理.docx_第2页
第2页 / 共8页
数据结构查找方法及原理.docx_第3页
第3页 / 共8页
数据结构查找方法及原理.docx_第4页
第4页 / 共8页
数据结构查找方法及原理.docx_第5页
第5页 / 共8页
点击查看更多>>
下载资源
资源描述

数据结构查找方法及原理.docx

《数据结构查找方法及原理.docx》由会员分享,可在线阅读,更多相关《数据结构查找方法及原理.docx(8页珍藏版)》请在冰豆网上搜索。

数据结构查找方法及原理.docx

数据结构查找方法及原理

【数据结构】查找:

线性表的查找

2010-09-0313:

01:

26|分类:

数据结构|标签:

|字号大中小订阅

本章简介

 由于查找运算的使用频率很高,几乎在任何一个计算机系统软件和应用软件中都会涉及到,所以当问题所涉及的数据量相当大时,查找方法的效率就显得格外重要。

在一些实时查询系统中尤其如此。

因此,本章将系统地讨论各种查找方法,并通过对它们的效率分析来比较各种查找方法的优劣。

查找的基本概念

1、查找表和查找

 一般,假定被查找的对象是由一组结点组成的表(Table)或文件,而每个结点则由若干个数据项组成。

并假设每个结点都有一个能惟一标识该结点的关键字。

 查找(Searching)的定义是:

给定一个值K,在含有n个结点的表中找出关键字等于给定值K的结点。

若找到,则查找成功,返回该结点的信息或该结点在表中的位置;否则查找失败,返回相关的指示信息。

2、查找表的数据结构表示

(1)动态查找表和静态查找表

 若在查找的同时对表做修改操作(如插入和删除),则相应的表称之为动态查找表。

否则称之为静态查找表。

(2)内查找和外查找

 和排序类似,查找也有内查找和外查找之分。

若整个查找过程都在内存进行,则称之为内查找;反之,若查找过程中需要访问外存,则称之为外查找。

3、平均查找长度ASL

 查找运算的主要操作是关键字的比较,所以通常把查找过程中对关键字需要执行的平均比较次数(也称为平均查找长度)作为衡量一个查找算法效率优劣的标准。

平均查找长度ASL(AverageSearchLength)定义为:

其中:

 ①n是结点的个数;

 ②Pi是查找第i个结点的概率。

若不特别声明,认为每个结点的查找概率相等,即

pl=p2…=pn=1/n

 ③ci是找到第i个结点所需进行的比较次数。

注意:

 为了简单起见,假定表中关键字的类型为整数:

typedefintKeyType;//KeyType应由用户定义

顺序查找(SequentialSearch)

 在表的组织方式中,线性表是最简单的一种。

顺序查找是一种最简单的查找方法。

1、顺序查找的基本思想

 基本思想是:

从表的一端开始,顺序扫描线性表,依次将扫描到的结点关键宇和给定值K相比较。

若当前扫描到的结点关键字与K相等,则查找成功;若扫描结束后,仍未找到关键字等于K的结点,则查找失败。

2、顺序查找的存储结构要求

  顺序查找方法既适用于线性表的顺序存储结构,也适用于线性表的链式存储结构(使用单链表作存储结构时,扫描必须从第一个结点开始)。

3、基于顺序结构的顺序查找算法

(1)类型说明

typedefstruct{

KeyTypekey;

InfoTypeotherinfo;//此类型依赖于应用

}NodeType;

typedefNodeTypeSeqList[n+1];//0号单元用作哨兵

(2)具体算法

intSeqSearch(SeqlistR,KeyTypeK)

{//在顺序表R[1..n]中顺序查找关键字为K的结点,

//成功时返回找到的结点位置,失败时返回0

inti;

R[0].key=K;//设置哨兵

for(i=n;R[i].key!

=K;i--);//从表后往前找

returni;//若i为0,表示查找失败,否则R[i]是要找的结点

}//SeqSearch

注意:

 监视哨设在高端的顺序查找【参见练习】

(3)算法分析

①算法中监视哨R[0]的作用

为了在for循环中省去判定防止下标越界的条件i≥1,从而节省比较的时间。

②成功时的顺序查找的平均查找长度:

 在等概率情况下,pi=1/n(1≤i≤n),故成功的平均查找长度为

(n+…+2+1)/n=(n+1)/2

即查找成功时的平均比较次数约为表长的一半。

 若K值不在表中,则须进行n+1次比较之后才能确定查找失败。

③表中各结点的查找概率并不相等的ASL

顺序查找演示过程【动画演示】

 【例】在由全校学生的病历档案组成的线性表中,体弱多病同学的病历的查找概率必然高于健康同学的病历,由于上式的ASLsq在pn≥pn-1≥…≥p2≥p1时达到最小值。

若事先知道表中各结点的查找概率不相等和它们的分布情况,则应将表中结点按查找概率由小到大地存放,以便提高顺序查找的效率。

 为了提高查找效率,对算法SeqSearch做如下修改:

每当查找成功,就将找到的结点和其后继(若存在)结点交换。

这样,使得查找概率大的结点在查找过程中不断往后移,便于在以后的查找中减少比较次数。

④顺序查找的优点

 算法简单,且对表的结构无任何要求,无论是用向量还是用链表来存放结点,也无论结点之间是否按关键字有序,它都同样适用。

⑤顺序查找的缺点

  查找效率低,因此,当n较大时不宜采用顺序查找。

二分查找

1、二分查找(BinarySearch)

 二分查找又称折半查找,它是一种效率较高的查找方法。

 二分查找要求:

线性表是有序表,即表中结点按关键字有序,并且要用向量作为表的存储结构。

不妨设有序表是递增有序的。

2、二分查找的基本思想

 二分查找的基本思想是:

(设R[low..high]是当前的查找区间)

(1)首先确定该区间的中点位置:

(2)然后将待查的K值与R[mid].key比较:

若相等,则查找成功并返回此位置,否则须确定新的查找区间,继续二分查找,具体方法如下:

 ①若R[mid].key>K,则由表的有序性可知R[mid..n].keys均大于K,因此若表中存在关键字等于K的结点,则该结点必定是在位置mid左边的子表R[1..mid-1]中,故新的查找区间是左子表R[1..mid-1]。

 ②类似地,若R[mid].key

下一次查找是针对新的查找区间进行的。

 因此,从初始的查找区间R[1..n]开始,每经过一次与当前查找区间的中点位置上的结点关键字的比较,就可确定查找是否成功,不成功则当前的查找区间就缩小一半。

这一过程重复直至找到关键字为K的结点,或者直至当前的查找区间为空(即查找失败)时为止。

3、二分查找算法

intBinSearch(SeqListR,KeyTypeK)

{//在有序表R[1..n]中进行二分查找,成功时返回结点的位置,失败时返回零

intlow=1,high=n,mid;//置当前查找区间上、下界的初值

while(low<=high){//当前查找区间R[low..high]非空

mid=(low+high)/2;

if(R[mid].key==K)returnmid;//查找成功返回

if(R[mid].kdy>K)

high=mid-1;//继续在R[low..mid-1]中查找

else

low=mid+1;//继续在R[mid+1..high]中查找

}

return0;//当low>high时表示查找区间为空,查找失败

}//BinSeareh

二分查找算法亦很容易给出其递归程序【参见练习】

4、二分查找算法的执行过程

  设算法的输入实例中有序的关键字序列为

(05,13,19,21,37,56,64,75,80,88,92)

要查找的关键字K分别是21和85。

具体查找过程【参见动画演示】

5、二分查找判定树

 二分查找过程可用二叉树来描述:

把当前查找区间的中间位置上的结点作为根,左子表和右子表中的结点分别作为根的左子树和右子树。

由此得到的二叉树,称为描述二分查找的判定树(DecisionTree)或比较树(ComparisonTree)。

注意:

 判定树的形态只与表结点个数n相关,而与输入实例中R[1..n].keys的取值无关。

 【例】具有11个结点的有序表可用下图所示的判定树来表示。

(1)二分查找判定树的组成

  ①圆结点即树中的内部结点。

树中圆结点内的数字表示该结点在有序表中的位置。

  ②外部结点:

圆结点中的所有空指针均用一个虚拟的方形结点来取代,即外部结点。

  ③树中某结点i与其左(右)孩子连接的左(右)分支上的标记"<"、"("、">"、")"表示:

当待查关键字KR[i].key)时,应走左(右)分支到达i的左(右)孩子,将该孩子的关键字进一步和K比较。

若相等,则查找过程结束返回,否则继续将K与树中更下一层的结点比较。

(2)二分查找判定树的查找

  二分查找就是将给定值K与二分查找判定树的根结点的关键字进行比较。

若相等,成功。

否则若小于根结点的关键字,到左子树中查找。

若大于根结点的关键字,则到右子树中查找。

  【例】对于有11个结点的表,若查找的结点是表中第6个结点,则只需进行一次比较;若查找的结点是表中第3或第9个结点,则需进行二次比较;找第1,4,7,10个结点需要比较三次;找到第2,5,8,11个结点需要比较四次。

 由此可见,成功的二分查找过程恰好是走了一条从判定树的根到被查结点的路径,经历比较的关键字次数恰为该结点在树中的层数。

若查找失败,则其比较过程是经历了一条从判定树根到某个外部结点的路径,所需的关键字比较次数是该路径上内部结点的总数。

【例】待查表的关键字序列为:

(05,13,19,21,37,56,64,75,80,88,92),若要查找K=85的记录,所经过的内部结点为6、9、10,最后到达方形结点"9-10",其比较次数为3。

 实际上方形结点中"i-i+1"的含意为被查找值K是介于R[i].key和R[i+1].key之间的,即R[i].key

(3)二分查找的平均查找长度

 设内部结点的总数为n=2h-1,则判定树是深度为h=lg(n+1)的满二叉树(深度h不计外部结点)。

树中第k层上的结点个数为2k-1,查找它们所需的比较次数是k。

因此在等概率假设下,二分查找成功时的平均查找长度为:

ASLbn≈lg(n+1)-1

  二分查找在查找失败时所需比较的关键字个数不超过判定树的深度,在最坏情况下查找成功的比较次数也不超过判定树的深度。

即为:

  二分查找的最坏性能和平均性能相当接近。

6、二分查找的优点和缺点

  虽然二分查找的效率高,但是要将表按关键字排序。

而排序本身是一种很费时的运算。

既使采用高效率的排序方法也要花费O(nlgn)的时间。

  二分查找只适用顺序存储结构。

为保持表的有序性,在顺序结构里插入和删除都必须移动大量的结点。

因此,二分查找特别适用于那种一经建立就很少改动、而又经常需要查找的线性表。

  对那些查找少而又经常需要改动的线性表,可采用链表作存储结构,进行顺序查找。

链表上无法实现二分查找。

分块查找

 分块查找(BlockingSearch)又称索引顺序查找。

它是一种性能介于顺序查找和二分查找之间的查找方法。

1、二分查找表存储结构

 二分查找表由"分块有序"的线性表和索引表组成。

(1)"分块有序"的线性表

 表R[1..n]均分为b块,前b-1块中结点个数为

,第b块的结点数小于等于s;每一块中的关键字不一定有序,但前一块中的最大关键字必须小于后一块中的最小关键字,即表是"分块有序"的。

(2)索引表

 抽取各块中的最大关键字及其起始位置构成一个索引表ID[l..b],即:

ID[i](1≤i≤b)中存放第i块的最大关键字及该块在表R中的起始位置。

由于表R是分块有序的,所以索引表是一个递增有序表。

  【例】下图就是满足上述要求的存储结构,其中R只有18个结点,被分成3块,每块中有6个结点,第一块中最大关键字22小于第二块中最小关键字24,第二块中最大关键字48小于第三块中最小关键字49。

2、分块查找的基本思想

  分块查找的基本思想是:

(1)首先查找索引表

  索引表是有序表,可采用二分查找或顺序查找,以确定待查的结点在哪一块。

(2)然后在已确定的块中进行顺序查找

  由于块内无序,只能用顺序查找。

3、分块查找示例

【例】对于上例的存储结构:

(1)查找关键字等于给定值K=24的结点

  因为索引表小,不妨用顺序查找方法查找索引表。

即首先将K依次和索引表中各关键字比较,直到找到第1个关键宇大小等于K的结点,由于K<48,所以关键字为24的结点若存在的话,则必定在第二块中;然后,由ID[2].addr找到第二块的起始地址7,从该地址开始在R[7..12]中进行顺序查找,直到R[11].key=K为止。

(2)查找关键字等于给定值K=30的结点

  先确定第二块,然后在该块中查找。

因该块中查找不成功,故说明表中不存在关键字为30的结点。

  具体过程【参见动画演示】

4、算法分析

(1)平均查找长度ASL

  分块查找是两次查找过程。

整个查找过程的平均查找长度是两次查找的平均查找长度之和。

①以二分查找来确定块,分块查找成功时的平均查找长度

ASLblk=ASLbn+ASLsq≈lg(b+1)-1+(s+1)/2≈lg(n/s+1)+s/2

②以顺序查找确定块,分块查找成功时的平均查找长度

ASL'blk=(b+1)/2+(s+1)/2=(s2+2s+n)/(2s)

注意:

当s=

时ASL'blk取极小值

+1,即当采用顺序查找确定块时,应将各块中的结点数选定为

  【例】若表中有10000个结点,则应把它分成100个块,每块中含100个结点。

用顺序查找确定块,分块查找平均需要做100次比较,而顺序查找平均需做5000次比较,二分查找最多需14次比较。

  注意:

  分块查找算法的效率介于顺序查找和二分查找之间。

(2)块的大小

  在实际应用中,分块查找不一定要将线性表分成大小相等的若干块,可根据表的特征进行分块。

  【例】一个学校的学生登记表,可按系号或班号分块。

(3)结点的存储结构

  各块可放在不同的向量中,也可将每一块存放在一个单链表中。

(4)分块查找的优点

  分块查找的优点是:

  ①在表中插入或删除一个记录时,只要找到该记录所属的块,就在该块内进行插入和删除运算。

  ②因块内记录的存放是任意的,所以插入或删除比较容易,无须移动大量记录。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 农学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1