数据结构-- 查找
KEY
- 查找的基本概念
- 顺序查找法
- 折半查找法
- 散列(Hash)表及冲突解决策略
- 查找算法的分析及应用
记忆:
- 查找
- 查找表
- 各种经典查找方法的名字
- 散列
- 散列表
- 散列函数
- 冲突
运用
-
线性表查找方法
- 顺序查找
- 二分(折半)查找
-
搜索树查找方法
- 搜索树的构建
-
散列查找方法
- 散列表的构建
一、查找的基本概念
查找(search)
- 在一组数据项里面查找一个特定的元素
假定: k1 , k2 , …, kn 是互不相同的关键码值, 有一个包含 n 条 记录的集合 C , 形式如下: (k1 , I 1 ), (k2 , I 2 ), …, (kn , In )其中 Ij是与关键码值 kj相关联的信息,1 <= j <= n. 查找问题: 给定某个关键码值 K, 在 C 中定位记录 (kj , Ij ) , 使得 kj = K.
查找 就是定位关键码值 kj = K 的记录的系统化方法.
查找成功 就是找到至少一个关键码值为kj的记录,使得 kj= K. 查找结果给出整个记录的信息,或指示该记录在查 找表中的位置
查找不成功 就是找不到记录,使得 kj= K (可能不存在这样的记录). 查找结果给出“空记录”或“空指针”。
查找的分类
- 基于线性结构的查找方法 顺序表和线性表方法(lists, tables, arrays).
- 基于关键码值计算的方法 根据关键码值直接访问方法 (hashing)
- 基于搜索树的方法 树索引方法
查找表是由同一类型的数据元素(或记录)构成的集合。 由于“集合”中的数据元素之间存在着 松散的关系,因此查找表是一种应用灵便的结构。
静态查找表—支持构建和查找操作
动态查找表—支持构建、查找、插入和删除操作
二、基于线性结构的查找方法
主要写顺序查找和二分查找了,其他的懒得写了,基本没见考过
2.1 顺序查找
输入: 一组数据元素和待查找的值 将这组数据元素用线性表无序存储
顺序查找基本思想: 从线性表的一端开始,逐个进行元素的关键字 和给定(待查找的)值的比较,若某个元素的 关键字和给定值相等,则查找成功,找到所查 元素;反之,若直至线性表的另一端,都未有 元素的关键字与给定值相等,则查找不成功, 线性表中没有所查元素。
对一个未排序的线性表顺序查找, 在最差情况下需要 θ ( n ) \theta(n) θ(n)时间 ,
平均比较次数,时间开销为 T ( n ) = n p n + ∑ i = 0 n − 1 ( i + 1 ) p i T(n)=npn+\sum_{i=0}^{n-1}(i+1)p_i T(n)=npn+∑i=0n−1(i+1)pi
若假定查找的元素出现在第i个位置的概率 pi相等,则
T ( n ) = n + 1 + p n ( n − 1 ) 2 , n + 1 2 ≤ T ( N ) ≤ n T(n)=\frac{n+1+p_n(n-1)}{2},\frac{n+1}{2}\le T(N)\le n T(n)=2n+1+pn(n−1),2n+1≤T(N)≤n
在每次都是成功查找,且查找等概率的情况下,平均情况下需要 θ ( n ) \theta(n) θ(n)时间
空间开销:只需要存储被查找的元素,算法本身没有额外的空间开销
2.2 二分查找
输入: 一个有序(关键字可比大小)数据元素的数组 待查找的值
二分查找基本思想: 分治法 对待查找的有序序列的范围不断折半,逐步缩小范围直到找到或找不到元素为止。
2.2.1 非递归算法过程
二分查找过程:基于分治策略,采用迭代实现。
输入存储待查找的n个元素的递增有序数组,以及要查询的值K
定义两个指针l和r分别指示待查元素所在范围的下界和 上界,指针mid指示待查区间的中间位置。
若待查元素的范围大于1,则取待查范围中间位置的元素的关键字与给定(待查找的)值的比较,
若相等:则查找成功,结束
若小于:将待查找范围的下界和上界设为l到mid-1
若大于:将待查找范围的下界和上界设为mid+1到r
继续循环处理
否则,待查找范围中已没有元素,查找不成功。
2.2.2 伪代码
二分查找真的很容易出错,同学分享的一篇超级有用的博客!
(系列文章2)------你常写的二分查找,真的是没有bug吗?
int binary(int arr[],int n,int k)
{
int left=0,right=n-1,mid;//左闭右闭
while(left<=right)
{
mid=(left+right)/2;
if(arr[mid]==k) return mid;
else if(arr[mid]>k)
{
right=mid-1;
}
else{
left=mid+1;
}
}
return -1;
}
2.2.3 性能分析
时间开销: 运行时间模型化为递归 每次都将问题规模减小近一半
T ( n ) = T ( n / 2 ) + 1 n > 1 T(n)=T(n/2)+1 n>1 T(n)=T(n/2)+1n>1
T ( 1 ) = 1 T(1)=1 T(1)=1
→ T ( n ) = l o g n \rightarrow T(n)=logn →T(n)=logn
空间开销: 只需要存储被查找的元素,算法本身空间开销是 O(1)
2.2.4 二分查找特点
二分查找的要求:
- 必须采用顺序存储结构
- 必须按关键字大小有序排列
二分查找比较次数少,查找速度快,平均性能好
其缺点是要求待查表为有序表(而且限于顺序存储结构,线性链表的效率不佳),且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。
习题:
2015[HNU]
下列选项中,不能构成折半查找中关键字比较序列的是
A. 500,200,450,180
B. 500,450,200,180
C. 180,500,200,450
D. 180,200,500,450
解题思路:折半查找的算法思想
A:前三步吧区间固定在了200-450之间或者450-500之间,此时180是没办法查找的,所以此题选A
2016[HNU]
在有n(n>1000)个元素的升序数组A中查找关键字x。查找算法的伪代码如下所示。
k=O;
while(k<n且A[k]<x)
k=k+3;
if(k<n且A[k]==x)
查找成功;
else if(k-1<n且A[k-1]==x)
查找成功;
else if(k-2<n且A[k-2]==x)
查找成功;
else 查找失败;
本算法与折半查找算法相比,有可能具有更少比较次数的情形是
A.当x不在数组中
B.当x接近数组开头处
C.当x接近数组结尾处
D.当x位于数组中间位置
答案:B
2.3 访问频率有序的查找表
- 动机: 现实中,一个集合中每个记录被查找(访问) 的概率(或频率)是不同的
- 访问频率构建查找表基本思想: 根据估算的访问频率从高到低排列记录 执行顺序查找
假设知道每个记录被查找的概率是p;。
先放置请求频率最高的记录。 p i p_i pi是第i条记录被访问的概率
查找的开销为比较关键码的次数;访问第一条记录的代价:
1,访问第二条记录的代价:2…
预期的检索代价:
C ‾ = 1 p 1 + 2 p 2 + . . . + n p n . \overline C =1p_1 +2p_2+...+ np_n. C=1p1+2p2+...+npn.
2.4 自组织线性表
动机: 大多数应用,无法事先知道数据被访问到的频率 记录的访问概率可能随时间变化
自组织线性表基本思想: 根据实际的记录访问模式在线性表中修改记录顺序 使用自组织启发式规则决定如何重新排列线性表 查找时,依然执行顺序查找
自组织启发式规则(Self-organising heuristic)
- 计数方法(Count method):为每条记录保存 一个访问计数,而且一直按照这个顺序维护 记录.
- 移至前端法(Move to Front method): 如果找 到一条记录就把它放到线性表的最前面, 而把其他记录后退一个位置.
- 转置(Transpose method): 把找到的记录与 它在线性表中的前一条记录交换位置.
这三条规则选一个即可
因为需要频繁的变更节点位置,因此,实现自组织线性表的最好方式是链表 无需对线性表依关键码大小进行排序,插入一条 新记录(访问概率小)的代价很低。
自组织线性表实现简单,对于小规模的记录很可 能更有效率 不需要额外的空间开销
2.5 分块查找
动机: 大规模集合的顺序查找效率低,二分查找不适用于顺序文件的查找
分块查找(跳跃查找jump search)基本思想:
把一个大的线性表分解成若干块,每块中的元素可以任意存放,但块与块之间必须排序。 然后,构建一个有序的索引表 查找时,先通过索引表查找合适的块,然后在该块中进行查找
一般情况下,不妨令整个查找表长为n,均匀划分为b块,每块含数据元素个数s=n/b;假定在索引表查找到每一块和块内查找到每个关键字都是等概率的,即概率分别为1/b和1 /s 。
顺序查找法确定块
A S L = 1 b ∑ j = 1 b j + 1 s ∑ i = 1 s i = 1 2 ( n s + s ) + 1 ASL= \frac{1}{b}\sum_{j=1}^{b} j+\frac{1}{s}\sum_{i=1}^{s}i=\frac{1}{2}(\frac ns + s )+1 ASL=b1j=1∑bj+s1i=1∑si=21(sn+s)+1
显然,当s= n \sqrt n n时,ASL达到最小值。折半查找法确定块
A S L ≈ l o g 2 ( n / s + 1 ) + s / 2 ASL \approx log_2(n/s+1)+s/2 ASL≈log2(n/s+1)+s/2
2.5.1 存储结构
-
表R分为b块,每一块中的关键字不一定有序,但前一块中的最大关键字必须小于后一块中的最小关键字,即表是“分块有序”的。
-
抽取各块中的最大关键字及其起始位置构成 一个索引表, 由于表R是分块有序的,所以索引表是一个递增有序表。
如图:
特点
- 分块查找法需要划分块,建立分块索引表。其中,分块要求查找表呈现分块有序性,分块有序性通常属于“自然天成”的。(例如:高校历届毕业生的归档资料)。
- 可以建立多级分块索引表
2.5.2 基本思想
- 首先查找索引表 索引表是有序表,可采用二分查找或 顺序查找,以确定待查的结点在哪一块。
- 然后在已确定的块中进行顺序查找 由于块内无序,只能用顺序查找。
2.5.3 算法开销
- 时间开销:
查找的时间开销包括索引表的查找和块内查找设分块查找中将长为n的表分成均等的b个块,每块s个元素,则 b= ⌈ n / s ⌉ \lceil {n / s}\rceil ⌈n/s⌉
如果索引表中采用顺序查找,则 A S L = ( n / s + s ) / 2 + 1 ASL= (n/s+s)/2+1 ASL=(n/s+s)/2+1
如果索引表中采用折半查找,则 A S L = l o g 2 ( n / s + 1 ) + s / 2 ASL= log2(n/s+1) +s /2 ASL=log2(n/s+1)+s/2 - 空间开销:
需要存储索引的辅助数组
2.6 题目集合
2010
已知一个长度为16的顺序表L,其元素按关键字有序排列。若采用折半查找法查找一个L中不存在的元素,则关键字的比较次数最多的是___
最多-》找不到 最 多 次 数 = ⌊ l o g 2 ( n ) ⌋ + 1 最多次数=\lfloor log_2(n)\rfloor+1 最多次数=⌊log2(n)⌋+1
2013:
含4个数据元素的集合:S={“do” ,“for”, “repeat”, “while”},各元素的查找概率依次为: p1=0.35,p2=0.15, p3=0.15,p4=0.35。将S保存在一个长度为4的顺序表中,采用折半查找法,查找成功时的平均查找长度为2.2。
请回答:
(1)若采用顺序存储结构保存S,且要求平均查找长度更短,则元素应如何排列?应使用何种查找方法?查找成功时的平均查找长度是多少?
(2)若采用链式存储结构保存S,且要求平均查找长度更短,则元素应如何排列?应使用何种查找方法?查找成功时的平均查找长度是多少?
2015
下列选项中,不能构成折半查找中关键字比较序列的是
A. 500,200,450,180
B. 500,450,200,180
C. 180,500,200,450
D. 180,200,500,450
解题思路:折半查找的算法思想
A:前三步吧区间固定在了200-450之间或者450-500之间,此时180是没办法查找的,所以此题选A
2016
在有n(n>1000)个元素的升序数组A中查找关键字x。查找算法的伪代码如下所示。
k=O;
while(k<n且A[k]<x)
k=k+3;
if(k<n且A[k]==x)
查找成功;
else if(k-1<n且A[k-1]==x)
查找成功;
else if(k-2<n且A[k-2]==x)
查找成功;
else 查找失败;
本算法与折半查找算法相比,有可能具有更少比较次数的情形是
A.当x不在数组中
B.当x接近数组开头处
C.当x接近数组结尾处
D.当x位于数组中间位置
答案:B
三、基于树形结构的查找方法
主要有 AVL树 , B树 ,数字查找树(比如trie树,前缀树,基数树),考研时间问题,这部分不怎么出题,就不做整理了,以后有时间了一定补上!!!
主要搜集了一下考过的考研题,
2017[HNU]
解题思路:首先看节点总个数是奇数还是偶数,
- 奇数:左右子树节点个数相同且同构。
- 偶数:其中一棵子树的节点比另一棵的节点数多1,但是折半的过程要一致
A 10 B 11 c 9 d 10
bc排除 明显不同构。
折半查找树其实是一棵二叉排序树。
为什么折半过程一致? 其实折半查找树的节点个数的差异是因为向上取整或者向下取整。比如6个节点,向下取整会使得左边有2个 右边有3个,如果该取整采取这个策略,所有的子树应该都是同样的方向多一个。这也就是折半过程要一致的意思。
现在再解释一下为什么要同构?
其实很好理解,B为例,左子树最后都是只有左孩子的,这说明了这颗树是向上取整的,因为向下取整会导致右子树=左子树+1 或右=左 而B的右子树又向下取整了,自相矛盾。
因此无论是同构还是折半过程一致,都是要满足取整的过程不变。
D本来是根节点的左+1=右,然后再往下一层看,变成了左=右+1,这也就是折半过程不一致了。
因此答案是A
四、基于计算的查找方法⭐️
散列(哈希 hash)
- 动机: 追求更加快速的检索 通过对关键字K作某种算术运算,可以用O(1) 的时间开销完成查找
散列的基本思想:
- 散列是把键码的某些内容打乱,并且使用这种 部分的信息作为查找的基础
散列术语
- 散列: 把关键码值映射到表中的位置来访问记录 的过程.
- 存放记录的数组称为散列表(hash table) . 用HT来 表示.
- 把关键码值映射到(散列表)位置的函数称为散 列函数(hash function) . 通常用h 来表示.
- 两个不同的关键码值k1 和 k2 ,散列成相同的值 h(k1) = h(k2), 这种情况称为冲突. 寻找一个替代位置的过程称为冲突解决策略
散列方法的分类
-
静态散列:散列表固定大小
-
动态散列:发生冲突后散列表大小变化
-
内散列:针对内存中数据进行查找
-
外散列:适用于对外部存储设备的进行查找
-
散列的实用研究:散列技术的研究
-
散列的理论研究:设计O(1)时间开销的方法
4.1 散列表
散列表,是根据关键码值而直接进行访问的数据结构,是关联数组抽象数据结构的一种实现。
散列表或散列映射是一种数据结构,用以存储关键字和及其 关联的值。散列表的大小(槽的数目)用变量M表示,槽从 0到M-1编号.
散列表利用一个散列函数将关键字映射到其关联的值。通用惯例是,当关键字的实际存储数目相对于关键字取值范围较 小时,可以使用散列表。
散列表中的常见基本操作:创建一个新散列表;在散列表中搜索关键字;在散列表中插入一个新关键字在散列表中删除一个关键字。
4.2 散列方法的基本思想
散列方法的基本思想 散列法,也成为哈希法,杂凑法或关键字地址计算法
计算法查找的基本思想:
- 首先在元素的关键字k和元素的存储位置p之间 建立一个对应关系h,使得p=h(k),h称为散列 函数。
- 创建散列表时,计算h(k), 从h(k)开始,使用 (如果需要)冲突解决策略找到存储关键字为k的关键字的存储位置;
- 当查找关键字为k的元素时,再利用散列函数计算p=h(k),从h(k)开始,使用(如果需要)冲突解决策略找到包含关键字k的元素。
散列函数的设计思路
以除法为基础.
- 除留余数法,选择一个大于散列表大 小的素数作为除数
以乘法为基础.
- 平方取中法,先求关键字的平方,然 后取平方值中间几位作为函数值
多字符关键码的处理
- 折叠法,把多个字符组合成一个字
一个好的散列函数满足的要求:
- 计算应该非常快
- 应该使冲突极小化,产生伪随机数
4.3 哈希函数的构造方法
这里开始是看华科的mooc的笔记,感觉比lxh老师的ppt好懂一点。。
-
直接定址法
取关键字的某个线性函数作为哈希地址。
-
数字分析法
对于可能出现的关键字集,事先分析这些关键字的每一位,选择其中“若干”“随机”位构成其哈希地址。
取第四位和第五位,作为hash表的哈希地址。如H(k3)=87
-
平方取中法:取关键字平方后中间若干位为hash地址
中间的随机性高于两端
-
折叠法:将关键字分割成位数相同的若干个段,然后各段叠加求和作为哈希地址。
例如:每一种西文图书都有一个国际标准图书编号,它是一个10位的十进制数字,若要以它作关键字建立一个哈希表,当馆藏书种类不到10,000时,可采用此法构造一个四位数的哈希函数。
-
余数法
H ( k e y ) = k e y m o d p p ≤ m H(key)=key\mod p \ \ \ p\le m H(key)=keymodp p≤m
一般情况下 p为一个质数或为不含小于20质因子的一个合数
4.4 开放定址法
当关键字key在哈希函数H(key)出现冲突的情况时,在H(key)为起点,取一个增量di,作为下一个探测的位置。即:
H i ( k e y ) = ( H ( k e y ) + d i ) m o d m H_i(key)= (H(key)+d_i)\mod m Hi(key)=(H(key)+di)modm
其中,H(key)为哈希函数,m为哈希表长, d i d_i di为增量
对于增量di,可以有三种取法
4.4.1 线性探测法
di=i(i=1,2,3,…m-1)
线性探测法的地址增量di = 1, 2, … , m-1,其中,i为探测次数。该方法一次探测下一个地址,直到有空的地址后插入,若整个空间都找不到空余的地址,则产生溢出。
线性探测容易产生“聚集”现象。当表中的第i、i+1、i+2的位置上已经存储某些关键字,则下一次哈希地址为i、i+1、i+2、i+3的关键字都将企图填入到i+3的位置上,这种多个哈希地址不同的关键字争夺同一个后继哈希地址的现象称为“聚集”。聚集对查找效率有很大影响。
4.4.2 二次探测再散列
二次探测法的地址增量序列为 di = 1 2 , − 1 2 , 2 2 , − 2 2 , … , q 2 , − q 2 ( q ≤ m / 2 ) 1^2, -1^2, 2^2, -2^2,… , q^2, -q^2 (q \le m/2) 12,−12,22,−22,…,q2,−q2(q≤m/2)。二次探测能有效避免“聚集”现象,但是不能够探测到哈希表上所有的存储单元,但是至少能够探测到一半。
4.4.3 伪随机数再散列
具体实现时,应建立一个伪随机数发生器,(如i=(i+p) % m),并给定一个随机数做起点。
例如,已知哈希表长度m=11,哈希函数为:H(key)= key % 11,则H(47)=3,H(26)=4,H(60)=5,假设下一个关键字为69,则H(69)=3,与47冲突。
如果用线性探测再散列处理冲突,下一个哈希地址为H1=(3 + 1)% 11 = 4,仍然冲突,再找下一个哈希地址为H2=(3 + 2)% 11 = 5,还是冲突,继续找下一个哈希地址为H3=(3 + 3)% 11 = 6,此时不再冲突,将69填入5号单元。
如果用二次探测再散列处理冲突,下一个哈希地址为H1=(3 + 12)% 11 = 4,仍然冲突,再找下一个哈希地址为H2=(3 - 12)% 11 = 2,此时不再冲突,将69填入2号单元。
如果用伪随机探测再散列处理冲突,且伪随机数序列为:2,5,9,………,则下一个哈希地址为H1=(3 + 2)% 11 = 5,仍然冲突,再找下一个哈希地址为H2=(3 + 5)% 11 = 8,此时不再冲突,将69填入8号单元。
4.5 再哈希法
当关键字key在哈希函数H(key)出现“冲突情况”时,依次采用其它哈希函数RHi计算关键字key的下一个地址,直到冲突不再发生为止。
H i ( k e y ) = R H i ( k e y ) ( i = 1 , 2 , 3 , … , k ) H_i(key) = RH_i(key)(i=1,2,3,…,k) Hi(key)=RHi(key)(i=1,2,3,…,k)
(RHi(key)为不同的哈希函数)
4.6链地址法
图说明一切
4.7 公共溢出区法(桶式散列)
桶式散列 把散列表中的槽分成多个桶(bucket),包含一个溢出桶(overflow bucket).
散列函数把每条记录分配到某个桶的第一个槽中。如 果这个槽已经被占用, 那么就把这条记录在桶中向下移, 直到找到一个空槽。
如果一个桶中被完全占满,那么就把这条记录存储在表的溢出桶中. 当检索记录时,首先检查合适的桶,然后检查溢出桶.
4.8 总结
- “下一个地址”和“结束标志”是由处理冲突方法决定的;
- 查找算法中既使用了“算术”运算,又使用了“比较”运算;
- “插入”算法是在查找失败处增加新关键字;
- “创建”算法可以循环调用“插入”运算实现;
- “删除”运算的实现是在查找成功处删除某个数据元素。对于某些处理冲突的方法,删除实际上是填入“删除标志”。(用数组的就标志,用链表的就删除)
时间复杂度分析
线性探索法:
A S L 成 功 ≈ 1 2 ( 1 + 1 1 − α ) ASL_{成功}\approx \frac12(1+ \frac1{1-\alpha}) ASL成功≈21(1+1−α1)
A S L 失 败 ≈ 1 2 ( 1 + 1 ( 1 − α ) 2 ) ASL_{失败}\approx \frac12(1+ \frac1{(1-\alpha)^2}) ASL失败≈21(1+(1−α)21)
二次探索法:
A S L 成 功 ≈ − 1 α l n ( 1 − α ) ASL_{成功}\approx -\frac1\alpha ln (1-\alpha) ASL成功≈−α1ln(1−α)
A S L 失 败 ≈ 1 1 − α ASL_{失败}\approx\frac1 {1-\alpha} ASL失败≈1−α1
链接地址法:
A S L 成 功 ≈ 1 + α 2 ASL_{成功}\approx 1+\frac\alpha2 ASL成功≈1+2α
A S L 失 败 ≈ α + e − a ASL_{失败}\approx \alpha+e^{-a} ASL失败≈α+e−a
α称为哈希表的装填因子,即:哈希表中填入的关键字个数与哈希表长之比。
在实际应用中,如果需要与检索相关的查找,插入和删除 操作的时间复杂度为O(1),散列可以提供平均时间复杂度为O(1)的实现方法,尽管在最差情况下散列的时间复杂性仍然是O(n)。
散列表的优势就是速度,对于大规模的记录,如果大小不 变,经过精心设计散列函数和散列表,可以实现高效的查找
散列方法适合精确查找,不适合范围查找散列表的记录均匀分布是难点,散列函数的高效性是难点 散列的查找效率是分摊分析,是概率,对一次查找来说,其性能无法保证
散列查找的应用
- 关联数组,数据库索引,缓存,集合等需要查找的计算机软件
- 编译器中使用散列表(符号表)跟踪源代码中的声明的变量。
- 散列表对图论问题中结点信息的编号
- 计算机下棋等游戏中,用散列表实现变换表加快游戏树的搜索
不适用散列表的问题
- 需要数据排序的问题。
- 数据具有多维性的问题。
- 需要前缀搜索特别是如果关键字很长且其长度是变化的问题。
- 包含动态数据的问题。
- 数据不具有唯一关键字的问题。
关于查找方法的几个结论
要实现查找,首先要选择合适的数据结构
- 基于线性结构查找表
- 简单易用,适用性广,常用于静态查找
- 不适合大规模数据集合
- 基于树形结构查找表
- 动态查找,适用于大规模数据集合
- 适用于多种查询需求
- 哈希结构 – 动态查找,适用于大规模数据集合 – 只适用于精确匹配查询
每种查找方法在不用环境下有不同的性能表现, 从而使其成为某种特定环境下的可选方法
题目整理
2010.将关键字序列(7、8、30、11、18、9、14)散列存储到散列表中。散列表的存储空间是一个下标从0开始的一维数组,散列函数为:H(key)= (key x 3)MOD 7,处理冲突采用线性探测再散列法,要求装填(载)因子为0.7。
1.请画出所构造的散列表。
2.分别计算等概率情况下查找成功和查找不成功
的平均查找长度。
2011.为提高散列(Hash)表的查找效率,可以采取的正确措施是
I .增大装填(载)因子
l .设计冲突(碰撞)少的散列函数
Ⅲ.处理冲突(碰撞)时避免产生聚集(堆积)现象
A.仅Ⅰ
B.仅Ⅱ
C.仅Ⅰ 、ll
D.仅Ⅱ、Ⅲ
2014.用哈希(散列)方法处理冲突(碰撞)时可能出现堆积(聚集)现象,下列选项中,会受堆积现象直接影响的是
A.存储效率
B.散列函数
C.装填(装载)因子
D.平均查找长度
2019.现有长度为11且初始为空的散列表HT,散列函数是H(key)=key %7,采用线性探查(线性探测再散列)法解决冲突将关键字序列87,40,30,6,11,22,98,20依次插入到HT后,HT查找失败的平均查找长度是
A. 4
B. 5.25
C. 6
D. 6.29