(1)rear=mid-1
(2)head=mid+1(3)head>rear
38.
(1)p!
=null
(2)pf=p(3)p!
=*t(4)*t=null
四.应用题
1.概念是基本知识的主要部分,要牢固掌握。
这里只列出一部分,目的是引起重视,解答略。
2.
(1)散列表存储的基本思想是用关键字的值决定数据元素的存储地址
(2)散列表存储中解决碰撞的基本方法:
①开放定址法形成地址序列的公式是:
Hi=(H(key)+di)%m,其中m是表长,di是增量。
根据di取法不同,又分为三种:
a.di=1,2,…,m-1称为线性探测再散列,其特点是逐个探测表空间,只要散列表中有空闲空间,就可解决碰撞,缺点是容易造成“聚集”,即不是同义词的关键字争夺同一散列地址。
b.di=12,-12,22,-22,…,k2(k≤m/2)称为二次探测再散列,它减少了聚集,但不容易探测到全部表空间,只有当表长为形如4j+3(j为整数)的素数时才有可能。
c.di=伪随机数序列,称为随机探测再散列。
②再散列法Hi=RHi(key)i=1,2,…,k,是不同的散列函数,即在同义词产生碰撞时,用另一散列函数计算散列地址,直到解决碰撞。
该方法不易产生“聚集”,但增加了计算时间。
③链地址法将关键字为同义词的记录存储在同一链表中,散列表地址区间用H[0..m-1]表示,分量初始值为空指针。
凡散列地址为i(0≤i≤m-1)的记录均插在以H[i]为头指针的链表中。
这种解决方法中数据元素个数不受表长限制,插入和删除操作方便,但增加了指针的空间开销。
这种散列表常称为开散列表,而①中的散列表称闭散列表,含义是元素个数受表长限制。
④建立公共溢出区设H[0..m-1]为基本表,凡关键字为同义词的记录,都填入溢出区
O[0..m-1]。
(3)用分离的同义词表和结合的同义词表解决碰撞均属于链地址法。
链地址向量空间中的每个元素不是简单的地址,而是关键字和指针两个域,散列地址为i(0≤i≤m-1)的第一个关键字存储在地址空间向量第i个分量的“关键字”域。
前者的指针域是动态指针,指向同义词的链表,具有上面③的优缺点;后者实际是静态链表,同义词存在同一地址向量空间(从最后向前找空闲单元),以指针相连。
节省了空间,但易产生“堆积”,查找效率低。
(4)要在被删除结点的散列地址处作标记,不能物理的删除。
否则,中断了查找通路。
(5)记录负载因子
3.评价哈希函数优劣的因素有:
能否将关键字均匀影射到哈希空间上,有无好的解决冲突的方法,计算哈希函数是否简单高效。
由于哈希函数是压缩映像,冲突难以避免。
解决冲突的方法见上面2题。
4.哈希方法的平均查找路长主要取决于负载因子(表中实有元素数与表长之比),它反映了哈希表的装满程度,该值一般取0.65~0.9。
解决冲突方法见上面2题。
5.不一定相邻。
哈希地址为i(0≤i≤m-1)的关键字,和为解决冲突形成的探测序列i的同义词,都争夺哈希地址i。
6.
散列地址
0
1
2
3
4
5
6
7
8
9
关键字
14
01
9
23
84
27
55
20
比较次数
1
1
1
2
3
4
1
2
平均查找长度:
ASLsucc=(1+1+1+2+3+4+1+2)/8=15/8
以关键字27为例:
H(27)=27%7=6(冲突)H1=(6+1)%10=7(冲突)
H2=(6+22)%10=0(冲突)H3=(6+33)%10=5所以比较了4次。
7.由于装填因子为0.8,关键字有8个,所以表长为8/0.8=10。
(1)用除留余数法,哈希函数为H(key)=key%7
(2)
散列地址
0
1
2
3
4
5
6
7
8
9
关键字
21
15
30
36
25
40
26
37
比较次数
1
1
1
3
1
1
2
6
(3)计算查找失败时的平均查找长度,必须计算不在表中的关键字,当其哈希地址为i(0≤i≤m-1)时的查找次数。
本例中m=10。
故查找失败时的平均查找长度为:
ASLunsucc=(9+8+7+6+5+4+3+2+1+1)/10=4.6ASLsucc=16/8=2
(4)intDelete(inth[n],intk)
//从哈希表h[n]中删除元素k,若删除成功返回1,否则返回0
{i=k%7;//哈希函数用上面
(1),即H(key)=key%7
if(h[i]==maxint)//maxint解释成空地址
printf(“无关键字%d\n”,k);return(0);}
if(h[i]==k){h[i]=-maxint;return
(1);}//被删元素换成最大机器数的负数
else//采用线性探测再散列解决冲突
{j=i;
for(d=1;d≤n-1;d++)
{i=(j+d)%n;//n为表长,此处为10
if(h[i]==maxint)return(0);//maxint解释成空地址
if(h[i]==k){h[i]=-maxint;return
(1);}
}//for
}
printf(“无关键字%d\n”,k);return(0)
}
8.
散列地址
0
1
2
3
4
5
6
7
8
9
关键字
15
24
10
19
17
38
18
40
比较次数
1
1
2
1
4
5
5
5
哈希表a:
ASLsucc=24/8=3;
散列地址
0
1
2
3
4
5
6
7
8
9
关键字
15
17
24
10
19
40
38
18
比较次数
1
3
1
2
1
2
4
4
哈希表b:
ASLsucc=18/8
9.
(1)
散列地址
0
1
2
3
4
5
6
7
8
9
10
11
12
关键字
13
22
53
1
41
67
46
51
30
比较次数
1
1
1
2
1
2
1
1
1
(2)装填因子=9/13=0.7(3)ASLsucc=11/9(4)ASLunsucc=29/13
10.11.ASLsucc=19/12
12.常用构造哈希函数的方法有:
(1)数字分析法该法事先需知道关键字集合,且关键字位数比散列表地址位数多,应选数字分布均匀的位。
(2)平方取中法将关键字值的平方取中间几位作哈希地址。
(3)除留余数法H(key)=key%p,通常p取小于等于表长的最大素数。
(4)折叠法将关键字分成长度相等(最后一段可不等)的几部分,进行移位叠加或间界叠加,其值作哈希地址。
(5)基数转换法两基数要互素,且后一基数要大于前一基数。
在哈希表中删除一个记录,在拉链法情况下可以物理地删除。
在开放定址法下,不能物理地删除,只能作删除标记。
该地址可能是该记录的同义词查找路径上的地址,物理的删除就中断了查找路径。
因为查找时碰到空地址就认为是查找失败。
散列地址
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
关键字
14
01
68
27
55
19
20
84
79
23
11
10
比较次数
1
2
1
4
3
1
1
3
9
1
1
3
13.
(1)
散列地址
0
1
2
3
4
5
6
7
8
9
10
关键字
4
12
49
38
13
24
32
21
比较次数
1
1
1
2
1
2
1
2
ASLsucc=(1+1+1+2+1+2+1+2)/8=11/8
ASLunsucc=(1+2+1+8+7+6+5+4+3+2+1)/11=40/11
(2)
13题图ASLsucc=11/8ASLunsucc=19/1114题
(2)ASLsucc=13/8ASLunsucc=19/11
值得指出,对用拉链法求查找失败时的平均查找长度有两种观点。
其一,认为比较到空指针算失败。
以本题为例,哈希地址0、2、5、7、9和10均为比较1次失败,而哈希地址1和3比较2次失败,其余哈希地址均为比较3次失败,因此,查找失败时的平均查找长度为19/11,我们持这种观点。
还有另一种理解,他们认为只有和关键字比较才计算比较次数,而和空指针比较不计算。
照这种观点,本题的ASLunsucc=(1+1+2+2+2)/11=8/11
14.由hashf(x)=xmod11可知,散列地址空间是0到10,由于有8个数据,装载因子取0.7。
(1)
散列地址
0
1
2
3
4
5
6
7
8
9
10
关键字
33
1
13
12
34
38
27
22
比较次数
1
1
1
3
4
1
2
8
ASLsucc=21/8ASLunsucc=47/11
15.
(1)ASL=42/12
(2)a:
ASLsucc=31/12
(2)b:
ASLsucc=18/12(注:
本题[x]取小于等于x的最大整数)
16.
17.查找时,对关键字49,22,38,32,13各比较一次,对21,18各比较两次
18.ASLsucc=15/10
19.ASLsuss=16/11
20.
散列地址
0
1
2
3
4
5
6
7
8
9
10
11
关键字
231
89
79
25
47
16
38
82
51
39
151
比较次数
1
1
1
1
2
1
2
3
2
4
3
ASLsucc=21/11
21.
散列地址
0
1
2
3
4
5
6
7
8
9
10
关键字
22
33
46
13
01
67
41
53
30
比较次数
1
2
1
2
4
5
1
1
3
22.
(1)
散列地址
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
关键字
32
17
63
49
24
40
10
30
31
46
47
比较次数
1
1
6
3
1
2
1
1
1
3
3
(2)查找关键字63,H(k)=63MOD16=15,依次与31,46,47,32,17,63比较。
(3)查找关键字60,H(k)=60MOD16=12,散列地址12内为空,查找失败。
(4)ASLsucc=23/11
23.设用线性探测再散列解决冲突,根据公式Snl≈(1+1/(1-α))/2。
可求出负载因子为α=0.67。
再根据数据个数和装载因子,可求出表长m=15/0.67,取m=23。
设哈希函数H(key)=(关键字首尾字母在字母表中序号之和)MOD23。
从上表求出查找成功时的平均查找长度为ASLsucc=19/15<2.0,满足要求。
24.
(1)哈希函数H(key)=(关键字各字符编码之和)MOD7
(2)
散列地址
0
1
2
3
4
5
6
7
8
9
关键字
be
cd
aa
ab
ac
ad
bd
bc
ae
ce
比较次数
1
2
1
1
1
1
1
3
3
9
25.α=0.7,所以表长取m=7/0.7=10
散列地址
0
1
2
3
4
5
6
7
8
9
关键字
SAT
WED
SUN
MON
TUE
THU
FRI
比较次数
6
1
1
1
2
3
4
ASLsucc=18/7ASLunsucc=32/10
26.
(1)
散列地址
0
1
2
3
4
5
6
7
8
9
10
11
12
关键字
27
53
2
31
19
20
8
18
比较次数
3
1
1
1
1
1
1
2
(2)ASLsuss=11/8
27.
(1)
散列地址
0
1
2
3
4
5
6
7
8
9
10
11
12
关键字
0
3
29
200
32
45
58
100
10
126
400
比较次数
1
1
2
1
1
2
3
1
1
3
3
关键字29和45各发生一次碰撞,关键字58,126和400各发生两次碰撞,其余关键字无碰撞。
(2)
散列地址
0
1
2
3
4
5
6
7
8
9
10
11
12
关键字
58
10
100
3
200
32
400
0
45
126
29
比较次数
1
1
2
1
3
1
3
8
1
2
1
发生碰撞次数:
100,126一次;200,400两次;0七次。
其余关键字无碰撞。
28.由α=0.75,得表长m=11/0.75=15
(1)散列函数H(k)=kMOD13(p取小于等于表长的最大素数)
(2)因为p=13,散列地址取0到12,用链地址法解决冲突,实际长就取13。
(2)ASLsucc=18/11(3)ASLunsucc=24/13
29.在B-树中查找关键字从根结点开始,从根往下查找结点,然后在结点内查找关键字,得出查找成功与否的结论。
B+树的非终端结点是索引部分,其查找从根开始,从根往下查到关键字后,要继续查到最下层结点,得到查找成功与否的结论。
另外,B+树还可以在最下层从最小关键字开始,从左往右进行顺序查找,B-树则不能作顺序查找。
30.m阶的B+树和B-树主要区别有三:
(1)有n棵子树的结点中含有n(B-树中n-1)个关键字;
(2)B+树叶子结点包含了全部关键字信息,及指向含关键字记录的指针,且叶子结点本身依关键字大小自小到大顺序链接;(3)B+树的非终端结点可以看成是索引部分,结点中只含其子树(根结点)中最大(或最小)关键字。
B+树的查找既可以顺序查找,也可以随机查找,B-只能顺序查找。
31.本题等价于“含有n个关键字的m阶B-树的最大高度是多少”?
一次检索中最多走一条从根到叶子的路径,由于根结点至少有两棵子树,其余每个(除叶子)结点至少有m/2棵子树,则第三层至少有m/2*2个结点,第l+1层至少有2*m/2l-1个结点。
设B-树深度为l+1,即第l+1层是叶子结点,叶子结点数是n+1(下面推导),故有n+1≥2*m/2l-1,即l≤logm/2()+1。
附:
推导B-树中叶子结点数s与关键字数n的关系式:
s=n+1
设B-树某结点的子树数为Ci,则该结点的关键字数Ni=Ci-1。
对于有k个结点的B-树,有
∑Ni=∑(Ci-1)=∑Ci-k(1≤i≤k)……
(1)
因为B树上的关键字数,即∑Ni=n(1≤i≤k)……
(2)
而B-树上的子树数可这样计算:
每个结点(除根结点)都是一棵子树,设叶子(子树)数为s;则
∑Ci=(k-1)+s(1≤i≤k)……(3)
综合
(1)
(2)(3)式,有s=n+1。
证毕。
32.表长m=12/0.6=20
(1)H(key)=keyMOD19
(2)两次碰撞。
开地址线性探测法解决冲突,即是用拉链法解决冲突。
见本章四第2题
(2)③
第32题用拉链法解决冲突
33.由于地址空间为10,且从100开始,故散列函数选为H(key)=key%7+100。
散列地址
100
101
102
103
104
105
106
107
108
109
关键字
98
63
79
17
53
19
61
75
46
49
比较次数
1
2
1
1
1
1
2
3
5
10
用线性探测再散列解决冲突,ASLsucc=27/10
34.
35.
36.第一层有1个结点,第二层至少有2个结点,第三层有2*m/2个结点,第四层有2*m/22个结点,……,第h层至少有2*m/2h-2个结点(h≥2)。
结点总数是
1+2+2*m/2+2*m/22+…+2*m/2h-2=2*m/2h-1-1
37.
38.
39.
40.(该题答案不唯一。
如删P时,亦可将双亲结点中M下来与N一起并入左兄弟成为(KLMN)
41.满二叉检索树可以看作是三阶B-树(2—3树)。
B-树的插入和删除算法不适合满二叉检索树。
满二叉检索树插入和删除结点后均破坏了“多路平衡查找树”“叶子在同一层上”(查找失败结点)的定义。
42.
43.B+树的查找可从根结点开始随机查找,也可以从最小关键字起顺序查找。
44.含9个叶子结点的3阶B-树至少有4个非叶子结点,当每个非叶子结点均含3棵子树,第三层是叶子结点时就是这种情况。
当4层3阶B-树有10个叶子结点时,非叶子结点达到最大值8个,其中第一层一个,第二层两个,第三层五个非叶子结点。
45.在二叉排序树上查找关键字K,走了一条从根结点至多到叶子的路径,时间复杂度是O(logn),而在中序遍历输出的序列中查找关键字K,时间复杂度是O(n)。
按序输入建立的二叉排序树,蜕变为单枝树,其平均查找长度是(n+1)/2,时间复杂度也是O(n)。
46.按中序遍历序列将值1~9依次标上。
47.
ASLsucc=(1*1+2*2+4*3+4*4)/11=33/11
48.
ASLsucc=32/10
49.
(2)10,12,15,20,24,28,30,35,46,50,55,68
(3)ASLsucc=41/12
50.
51.