第九章 查找

一、静态查找表

查找表(table):同类型的DE(或记录)构成的集合

 

查找表上的基本运算:

建立查找表create(ST,n)

查找search(ST,k)

遍历查找表traverse(ST)

 

查找:在查找表中确定与给定值相等的DE的过程。

查找结果:

查找成功(table中存在给定的记录)

查找不成功(table中不存在给定值的记录)

查找表分为:

静态查找表(对查找表中的数据元素不进行插入或删除操作)

动态查找表(对查找表中的数据元素可进行插入和删除操作)

 

1、顺序表的查找

FUNC seqsrch1(r:sqlisttp;k:keytype):integer;

 r[0].key:=k;i:=n;

 WHILE r[i].key  <>k DO i:=i-1;

 RETURN(i)

ENDF;{seqsrch1}

1)查找过程:

从n开始,依次与k进行比较,若相等则查找成功;否则,继续进行,直到与r[0].key比较为止。

2)算法分析:

(1)算法结构应由一个循环构成;

(2)循环结束有两种可能:

3)查找成功:r[i].key=k

查找不成功 i=0

4)查找方向可换

FUNC seqsrch2(r:sqlisttp;k:keytype):integer;

 r[n+1].key:=k;i:=1;

 WHILE r[i].key  <>k DO i:=i+1;

  IFi=n+1 THEN RETURN(0)

 ELSE RETURN(i)

ENDF;{seqsrch2}

 

平均查找长度(ASL)

查找过程中,给定值需与关键字比较的次数的期望值。

ASL=PiCi

其中:Pi为查找第i个记录的概率;

      Ci为找到第i个记录时,已比较的次数。

顺序查找的平均查找长度ASLss=np1+(n-1)p2+……+pn

当pi=1/n时,ASLss=PiCi=(n+1)/2

2、有序表的查找

有序表:查找表中记录按关键字有序排列的表。即:r[i].key<= r[i+1].key i=1,2,…,n-1

折半查找:

要求:查找表为有序表;

查找过程:先确定待查记录范围;然后逐步缩小范围;直到查找成功或不成功。

折半查找算法

FUNC binsrch(r:ordlisttp;k:keytype):integer;

  low:=1;high:=n;found:=false;

 WHILE low≤high AND NOTfound DO

[mid:=(low+high)DIV 2

CASE

  k>r[mid].key:low:=mid+1;

  k=r[mid].key:found:=true;

k<r[mid].key:high:=mid-1;

ENDC;

]

  IFfound THEN RETURN(mid)ELSE RETURN(i)

ENDF;{ binsrch }

 

3.索引顺序表的查找(分块查找)

索引表:

1)按表中记录的关键字分块,R1,R2,……,RL

要求:第Rk块中的所有关键字<Rk+1块中的所有关键字 k=1,2,……,L-1,称为“分块有序”

2)对每块建立一个索引项,包含以两项内容:

(1)关键字项:为该块中最大关键字值;

(2)指针项:为该块第一个记录在表中位置。

3)所有索引项组成索引表

查找分为两步:

1)确定待查记录所在块;(可以用顺序或折半查找)

2)在块内顺序查找。(只能用顺序查找)

分块查找表的平均查找长度ASL=Lb+Lw

其中:Lb为查索引表确定所在块的平均查找长度;

Lw为在块内查找记录的平均查找长度;

 

二、动态查找表

动态查找表的特点:

表结构本身是在查找过程中动态生成的。即查找不成功时,将该记录插入动态查找表中

 

1、二叉排序树(Binary Sort Tree)(二叉查找树)

1)BST定义:

BST或者是一棵空树,或者是具有如下性质的BT:

若左子树非空,则左子树上所有结点的值均小于根结点的值;

若右子树非空,则右子树上所有结点的值均大于根结点的值;

左、右子树也为BST

2)查找过程为:

(1)当前BST非空时,将给定值k与当前根结点的关键字比较;

(2)若相等,查找成功,结束;

     若k小于当前根结点的关键字,则将左子树作为当前BST;

     若k大于当前根结点的关键字,则将右子树作为当前BST;

(3)重复(1)。

3)BST的特点:

(1)中序遍历BST可得到一个关键字的有序序列。

(2)在BST上插入新结点时,不必移动其他结点,仅需改动某结点的指针(因新结点总是BST上的一个新叶结点T。

(3)BST既具有类似折半查找的特性(与BST的平衡度有关)又采用了链表存储结构(折半查找不能为链表存储结构),因此,对于经常要进行查找、插入和删除记录的有序表,采用BST尤其适合。

4.BST的查找分析

BST上查找过程与折半查找类似,是从根结点到所找到结点的一条路径,与给定值比较次数等于该路径长度+1(即结点所在层次数),最大次数不超过树的深度。

但长度为n的所有折半查找表对应的判定树是唯一的,而含有n个结点的BST却不唯一。

因此,含有n个结点的BST的ASL和树的形态有关。

最差情况是BST退化为单支树,其深度为n,ASL=(n+1)/2(同顺序查找)

最好情况与折半查找相同,ASL=log2n

随机情况下,平均查找长度为1+4logn

为了避免出现单支树,在构成BST的过程中可进行“平衡化”处理。

 

2、平衡二叉树(Balanced Binary Tree)(又称AVL树)

1)AVL树定义:

AVL树或者是一棵空树,或者是具有下列性质的BT:

左、右子树均为AVL

且任一左、右子树的深度只差的绝对值不超过1

称某结点左子树的深度-右子树的深度为该结点的平衡因子

 

2)AVL树的结点

AVL树上任何结点的平衡因子只可能为-1,0或1;

AVL树的深度与logn同数量级;

完全二叉树一定是AVL,AVL树不一定是完全二叉树

 

3)BST变为AVL树

 

三、哈希查找表

通过计算来查找的新型方法——哈希法(Hash)或称杂凑法、散列法。

设关键字集合为A,地址空间为D,哈希法就是在A和D之间建立一种函数关系H,通过计算函数H(k),就能得到关键字k的地址

设D是长度为n的表,A是含m个记录的关键字集合,如果存在一个函数H,使得对A中任一关键字k,均有0≤H(Ki)≤n-1 i=1,2,……,m

同时,Ki所标示的记录Ri在表D中的地址是H(Ki),

则称函数H为关键字集合A到地址D之间的哈希函数,地址空间D为哈希表。

哈希函数不一定是一对一的,产生地址冲突

在应用哈希查找方法时,主要解决两个技术问题:

一是构造好哈希函数的方法;二是研究冲突解决的方法

 

1、哈希函数构造方法

计算简单容易,冲突极少

1)直接哈希函数

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

即:H(key)=key 或H(key)=a*key+b

2)数字分析法

设n个d位数的关键字,由r个不同的符号组成,此r个符号在关键字的各位出现的频率不一定相同,可能在某些位上均匀分布,即每个符号出现的次数都接近于n/r次,而在另外一些位上分布不均匀。则选择其中分布均匀的s位作为哈希地址,即H(key)=“key中数字均匀分布的s位”。H(key)

3)平均取中法

取关键字平方后的中间几位作为哈希地址,即哈希函数为:H(key)=“key平方的中间几位”其中,所取的位数由哈希表的大小确定。

4)折叠法

将关键字分割成位数相等的几部分(最后一部分位数可以不同),取这几部分叠加和(舍去高位的进位)作为哈希地址。位数由存储地址的位数确定

相加时有两种方法:

移位折叠加法:即将每部分得最后一位对齐,然后相加;

间界折叠加法:即将关键字看做一纸条,从一端向另一端沿间界逐次折叠,然后对齐相加

5)除留余数法

取关键字被某个不大于哈希表长m的数p除后的余数为哈希地址。

即H(key)=key MOD p,p≤m

P的选择很重要,选得不好回产生很多冲突,通常选择p≤m的某个质数。

6)随机数法

选择一个随机含糊,取关键字的随机函数值作为它的哈希地址。

即H(key)=random(key)

 

2、处理冲突的方法

冲突是指由关键字得到的Hash地址上已有其他地址,处理冲突就是为该关键字找到另一个“空”的Hash地址。

1)开放定址法

Hi=(H(key)+di)mod m   i=1,2,……,m-1;

其中:

Hi为第i次冲突的地址;

H(key)为Hash函数;

m为Hash表表长;

di为增量序列

线性探测再散列:di=1,2,3,……,m-1

二次线性探测再散列:di=12,-12,22,-22,32,……,±k2  |±k|≤m-1

伪随机探测再散列:di=伪随机序列

 

2)再哈希法

Hi=RHi(key) i=1,2,……,n

RHi为不同哈希函数

用n个不同哈希函数排成一个序列,当发生冲突时,由RHi确定第i次冲突的地址Hi

 

3)链地址法

将关键字发生冲突的记录存储在一个线性链表中

 

4)公共溢出区法

将同哈希表中关键字发生冲突的所有记录填入一个溢出表中。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值