李云清数据结构第九章检索

关注公众号凡花花的小窝,可以获取更多的计算机相关的资源
第9 章 检索
9.1 选择题
(1)在关键字序列(12,23,34,45,56,67,78,89,91)中二分查找关键字为45、
89 和12 的结点时,所需进行的比较次数分别为( B )。
A.4,4,3 B.4,3,3 C.3,4,4 D.3,3,4
(2)适用于折半查找的表的存储方式及元素排列要求为( D )。
A.链式方式存储,元素无序 B.链式方式存储,元素有序
C.顺序方式存储,元素无序 D.顺序方式存储,元素有序
(3)设顺序存储的线性表共有123 个元素,按分块查找的要求等分成3 块。若对索引表
采用顺序查找来确定块,并在确定的块中进行顺序查找,则在查找概率相等的情况下,分块查
找成功时的平均查找长度为( B )。
A.21 B.23 C.41 D.62
(4)已知含10 个结点的二叉排序树是一棵完全二叉树,则该二叉排序树在等概率情况下查
找成功的平均查找长度等于( B )。
A.1.0 B.2.9 C.3.4 D.5.5
(5)在图9.27 所示的各棵二叉树中,二叉排序树是( C )。
图9.27 题(5)图
(6)由同一关键字集合构造的各棵二叉排序树( B )。
A.其形态不一定相同,但平均查找长度相同
B.其形态不一定相同,平均查找长度也不一定相同
C.其形态均相同,但平均查找长度不一定相同
D.其形态均相同,平均查找长度也都相同
(7)有数据{53,30,37,12,45,24,96},从空二叉树开始逐步插入数据形成二叉排
序树,若希望高度最小,则应该选择下列( A )的序列输入。
A.37,24,12,30,53,45,96 B.45,24,53,12,37,96,30
C.12,24,30,37,45,53,96 D.30,24,12,37,45,96,53
(8)若在9 阶B-树中插入关键字引起结点分裂,则该结点在插入前含有的关键字个数为
( C )。
92
A.4 B.5 C.8 D.9
(9)对于哈希函数H(key) = key%13,被称为同义词的关键字是( D )。
A.35 和41 B.23 和39 C.15 和44 D.25 和51
(10)下列叙述中,不符合m 阶B 树定义要求的是( D )。
A.根结点最多有m 棵子树
B.所有叶结点都在同一层上
C.各结点内关键字均升序或降序排列
D.叶结点之间通过指针链接
9.2 在分块检索中,对256 个元素的线性表分成多少块最好?每块的最佳长度是多少?若每块
的长度为8,其平均检索的长度是多少?
【答】:对256 个元素的线性表分成16 块,每块的最佳长度是17;若每块的长度为8,当采用
顺序检索方法确定所在的块时平均检索长度是21,当采用二分检索方法确定所在的块时平
均检索长度是9。
9.3 设有关键码A、B、C 和D,按照不同的输入顺序,共可能组成多少不同的二叉排序树。
请画出其中高度较小的6 种。
【答】:共可能组成14 种不同形态的二叉排序树。其中高度较小的6 种如图9.28(a )所示。
其它8 种分别是高度为4 的二叉排序树如图9.28(b)所示。
(a) 4 个结点组成的高度较小的6 棵二叉排序树
(b) 4 个结点组成的高度为4 的二叉排序树
图9.28 4 个结点输入序列构成的不同二叉排序树
9.4 已知序列17,31,13,11,20,35,25,8,4,11,24,40,27。请画出由该输入序列构
成的二叉排序树,并分别给出下列操作后的二叉排序树。
(1)插入数据9;(2)删除结点17;(3)再删除结点13
【答】:该序列的二叉排序树如图9.29(a)所示,插入数据9 后的二叉排序树如图9.29(b)
所示,删除结点17 后的二叉排序树如图9.29(c)所示,再删除结点13 后的二叉排序树
如图9.29(d)所示。
93
(a) 二叉排序树 (b) 插入9 之后的二叉排序树
(c)删除17 之后的二叉排序树 (d)删除13 之后的二叉排序树
图9.29 二叉树结点插入与删除操作示例
9.5 试写一算法判别给定的二叉树是否为二叉排序树,设此二叉树以二叉链表为存储结构,且
树中结点的关键字均不相同。
【答】:判定二叉树是否为二叉排序树可以建立在二叉树中序遍历的基础上,在遍历中附设一
指针pre 指向树中当前访问结点的中序直接前驱,每访问一个结点就比较前驱结点pre 和
此结点是否有序;若遍历结束后各结点和其中序直接前驱均满足有序,则此二叉树即为二
叉排序树,否则不是二叉排序树。
二叉树存储结构定义为:
typedef int datatype;
typedef struct node /二叉树结点定义/
{ datatype data;
struct node *lchild,*rchild;
}bintnode;
typedef bintnode *bintree;
函数bisorttree()用于判断二叉树t 是否为二叉排序树,初始时pre=NULL;flag=1;结
束时若flag1,则此二叉树为二叉排序树,否则此二叉树不是二叉排序树。
void bisorttree(bintree t,bintree *pre,int *flag)
{if (t&& *flag
1)
{ bisorttree(t->lchild,pre,flag); /判断左子树/
if (preNULL) /访问中序序列的第一个结点时不需要比较/
94
{ *flag=1;
*pre=t;
}
else /比较t 与中序直接前驱pre 的大小(假定无相同关键字)/
{if ((*pre)->datadata)
{*flag=1;
pre=t;
}
else /
pre 与t 无序 */
*flag=0;
}
bisorttree(t->rchild,pre,flag); /判断右子树/
}
}
9.6 设T 是一棵给定的查找树,试编写一个在树T 中删除根结点值为a 的子树的程序。要求在
删除的过程中释放该子树中所有结点所占用的存储空间。这里假设树T 中的结点采用二
叉链表存储结构。
【答】:删除二叉树可以采用后序遍历方法,先删除左子树,再删除右子树,最后删除根结点。
本题先在指定的树中查找值为a 的结点,找到后删除该棵子树。相关函数实现如下(二叉
排序树的结构定义同题9.5)
/删除以t 为根的二叉树/
void deletetree(bintree *t)
{if (*t)
{deletetree(&(*t)->lchild); /递归删除左子树/
deletetree(&(*t)->rchild); /递归删除右子树/
free(*t); /删除根结点/
}
}
/删除二叉树中以根结点值为a 的子树/
void deletea(bintree *t,datatype a)
{bintree pre=NULL,p=*t;
while (p&&p->data!=a) /查找值为a 的结点/
{pre=p;
p=(adata)?p->lchild:p->rchild;
}
if (!pre) *t=NULL; /树根/
else /非树根/
if (pre->lchild
p) pre->lchild=NULL;
else pre->rchild=NULL;
95
deletetree(&p); /删除以p 为根的子树/
}
9.7 含有12 个节点的平衡二叉树的最大深度是多少(设根结点深度为0),并画出一棵这样的
树。
【答】:含有12 个节点的平衡二叉树的最大深度是4(设根结点深度为0),如果根结点的深度
为1 则本题的答案为5,该树如图9.30 所示。
图9.30 具有12 个结点的深度为4 的平衡二叉树
9.8 试用Adelson 插入方法依次把结点值为60,40,30,150,130,50,90,80,96,25 的
记录插入到初始为空的平衡二叉排序树中,使得在每次插入后保持该树仍然是平衡查找
树。请依次画出每次插入后所形成的平衡查找树。
【答】:由结点序列构成的平衡二叉排序树如图9.31 所示。
60 60
40
0
0
1
60
40 1
2
30
0
40
60
0
0
30
0
40
60
0
-1
30
-1
150 0
(a)空树(b)插入60(c)插入40 (d)插入30 (e)LL 型调整 (f)插入150
40
60
0
-1
30
-2
150 1
130 0
40
130
0
-1
30
0
150
0
60
0
40
130
0
-2
30
1
150
0
60
1
50
0
60
130
0
0
40
-1
150
0
50
0 0
30
(g)插入130 (h)RL 型调整 (i)插入50 (j)RL 型调整
96
(k)插入90 (l)插入80 (m)插入96 (n)插入25
图9.31 AVL 树的插入过程
9.9 结点关键字k1,k2,k3,k4,k5 为一个有序序列,它们的相对使用频率分别为p1=6,p2=8,
p3=12,p4=2,p5=16,外部结点的相对使用频率分别为q0=4,q1=9,q2=8,q3=12,q4=3,
q5=2。试构造出有序序列k1,k2,k3,k4,k5 所组成的最优查找树。
【答】:(略)
9.10 证明Huffman 算法能正确地生成一棵具有最小带权外部路枝长度的二叉树。
【答】:哈夫曼提出了一种构造最优前缀编码的贪心算法,由此产生的编码方案称为哈夫曼算
法。哈夫曼算法以自底向上的方式构造表示最优前缀码的二叉树T。算法以C 个叶结点
开始,执行C-1 次的“合并”运算后产生最终所要求的树T。要证明哈夫曼算法的正确性,
只要证明最优前缀码问题具有贪心选择性质和最优子结构性质。
(1)贪心选择性质
设C 是编码字符集,C 中字符c 的频率为f(c)。又设x 和y 是C 中具有最小频率的两个
字符,则存在C 的一个最优前缀编码使x 和y 具有相同码长且仅最后一们编码不同。
证明:设二叉树T 表示C 的任意一个最优前缀码。我们要证明可以对T 作适当修改后得
到一棵新的二叉树T’’,使得在新树中,x 和y 是最深中子且为兄弟。同时新树T’‘表示的前缀
码也是CS 的一个最优前缀码。如果我们能做到这一点,则x 和y 在T’‘表示的最优前缀码中就
具有相同的码长且仅最后一位编码不同。
设b 和c 是二叉树T 的最深叶子且为兄弟。不失一般性,可设f(b) ≤ f(c),f(x) ≤ f
(y)。由于x 和y 是C 中具有最小频率的两个字符,故f(x) ≤ f(b),f(y) ≤ f(c)。
首先在树T 中交换叶子b 和x 位置得到树T’,然后在树T’‘再交换叶子c 和y 的位置,得到树
T’’。如下图所示。
图 编码树T 的变换
由此可知,树T 和T’表示的前缀码的平均码长之差为
97
B(T)-B(T’)=Σ
c∈CS
T c d c f ) ( ) ( -Σ
c∈CS
T f ©d © ’
= ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ’ ’ f x d x f b d b f x d x f b d b T T T T + − −
= f (x)d (x) f (b)d (b) f (x)d (b) f (b)d (x) T T T T + − −
= ( f (b) − f (x))(d (b) − d (x)) ≥ 0 T T
最后一个不等式是因为f(b)-f(x)和dT(b)-dT(x)均为非负。
类似地,可以证明在T’中交换y 与c 的位置也不增加平均码长,即B(T’)-B(T’’)也是非负
的。由此可知B(T’’) ≤ B(T’) ≤ B(T)。另一方面,由于T 所表示的前缀码是最优的,
故B(T) ≤ B(T’’)。因此,B(T)=B(T’’),即T’‘表示的前缀码也是最优前缀码,且x
和y 具有最长的码长,同时仅最后一位编码不同。
(2)最优子结构性质
设T 是表示字符集C 的一个最优前缀码的二叉树。C 中字符c 的出现频率为f(c)。设x 和y
是树T 中的两个叶子且为兄弟,z 是它们的双亲。若将z 看作是具有频率f(z)=f(x)
+f(y)的字符,则树T’=T-{x,y}表示字符集C’=C-{x,y} ∪ {z}的确一个最优前缀码。
证明:我们首先证明T 的平均码长B(T)可用T’的平均码长B(T’)来表示。
事实上,对任意c∈C-{x,y}有,dT©=dT’(c),故有f(c)dT(c)=f(c)dT’(c)。
另一方面,dT(x)=dT(y)=dT’(z)+1,故
f(x)dT(x)+f(y)dT(y)=(f(x)+f(y))(dT’(z)+1)
=f(x)+f(y)+f(z)dT’(z)
由此即知,B(T)=B(T’)+f(x)+f(y)。
由T’所表示的字符集C’的前缀码不是最优的,则有T’‘表示的C’的前缀码使得B(T’’) (T’)。由于z 被看作是C’中的一个字符,故z 在T’‘中是一树叶。若将x 和y 加入T’‘中作
为z 的儿子,则得到表示字符集C 的前缀码的二叉树T’’’,且有
B(T’’’)=B(T’’)+f(x)+f(y) 这与T 的最优性矛盾。故T’所表示的C’的前缀码是最优的。
由贪心选择性质和最优子结构性质立即可推出:哈夫曼算法是正确的,Huffman 算法能正
确地生成一棵具有最小带权外部路枝长度的二叉树。Huffman Tree 产生C 的确一棵最优前缀
编码树。
9.11 假设通讯电文中只用到A,B,C,D,E,F 六个字母,它们在电文中出现的相对频率分
别为:8,3,16,10,5,20,试为它们设计Huffman 编码。
【答】:由A,B,C,D,E,F 建立的Huffman 树如下:
各字符对应的Huffman 编码为:
A:001
B:0000
C:10
98
D:01
E:0001
F:11
3 5
8
10 16 20
B E
A
D C F
8
16
26 36
62
9.12 含有9 个叶子结点的3 阶B-树中至少有多少个非叶子结点?含有10 个叶子结点的3 阶
__________B-树中至少有多少个非叶子结点?
【答】:(略)
9.13 编写在B-树中插入结点与删除结点的算法程序。
【答】:(略)
9.14 用依次输入的关键字23、30、51、29、27、15、11、17 和16 建一棵3 阶B-树,画出建
该树的变化过程示意图(每插入一个结点至少有一张图)。
【答】:(略)
9.15 设散列表长度为11,散列函数H(x)=x % 11,给定的关键字序列为:1,13,12,34,
38,33,27,22。试画出分别用拉链法和线性探测法解决冲突时所构造的散列表,并求出
在等概率的情况下,这两种方法查找成功和失败时的平均查找长度。
【答】:
(1)拉链法构造的散列表如下:
0
1
2
3
4
5
6
7
8
9
10
22 33
34 12 1
13
27 38
^
^
^
^
^
^
^
^
^
^
99
查找成功时的平均查找长度为:13/8
查找失败时的平均查找长度为:8/11
(2)线性探测法构造的散列表如下:
查找成功时的平均查找长度为:(1+1+3+4+1+1+2+8)/8=21/8
查找失败时的平均查找长度为:(1+2+3+…+11)/11=6 次
9.16 设散列表为T[0…12],即表的大小m=13。现采用再哈希法(双散列法)解决冲突。散列
函数和再散列函数分别为:
H0(k)=k % 13、 Hi=(Hi-1+REV(k+1)%11+1)%13;i=1,2,…,m-1
其中,函数REV(x)表示颠倒10 进制数的各位,如REV(37)=73,REV(1)=1 等。
若插入的关键码序列为{2,8,31,20,19,18,53,27}。
(1)试画出插入这8 个关键码后的散列表。
(2)计算检索成功的平均查找长度ASL。
【答】:(1)
H0(2)=2,2 存入2 号。
H0(8)=8,8 存入8 号。
H0(31)=5,31 存入5 号。
H0(20)=7,20 存入7 号。
H0(19)=6,19 存入6 号。
H0(18)=5,出现碰撞,H1(18)=(5+91%11+1)%13=9,18 存入9 号。
H0(53)=1,53 存入1 号。
H0(27)=1,出现碰撞,H1(27)=(1+82%11+1)%13=7,发生碰撞,H2(27)=(7+82%11+1)
%13=0,27 存入0 号。
插入8 个关键码序列以后的散列表如下所示:
(2)检索成功的平均查找长度是1.375。
位置 0 1 2 3 4 5 6 7 8 9 10 11 12
关键码 27 53 2 31 19 20 8 5
100

你可能感兴趣的:(数据结构)