二.填空题
1. 已知 L 是无头结点的单链表,试从下列提供的答案中选择合适的语句序列,实现在表首插入 S 结点的语句序列是【】。 ①P->next=S; ②P=L; ③L=S; ④P->next=S->next; ⑤S->next= P->next; ⑥S->next=L; ⑦S->next=NULL; ⑧while (P->next!=Q) P=P->next; ⑨while (P->next!=NILL) P=P->next; 答案:⑥③
解析:
在无头结点的单链表中,要在表首插入一个新结点 S,我们需要将新结点 S 的 next 指针指向当前的表头 L,然后更新表头 L 为新结点 S。下面是实现这一操作的步骤和对应的语句序列:
首先,新结点 S 的 next 指针应该指向当前的表头 L(如果 L 不为空)。
然后,更新表头 L 为新结点 S。
根据这两个步骤,我们可以选择以下语句序列:
S->next = L; // 将 S 的 next 指针指向当前的表头 L
L = S; // 更新表头 L 为新结点 S
从提供的答案中选择对应的语句,我们得到:
⑥ S->next = L;
③ L = S;
因此,实现在表首插入 S 结点的语句序列是:
⑥③
即先执行 S->next = L;,再执行 L = S;。
其他提供的语句在这个特定的任务中是不需要的:
① P->next = S; 是用于在某个位置后插入新结点的。
② P = L; 和 ⑧ while (P->next != Q) P = P->next; 以及 ⑨(注意这里应该是 NULL 而不是 NILL)是用于查找某个结点的。
④ P->next = S->next; 和 ⑤ S->next = P->next; 通常用于结点的删除或重新链接。
⑦ S->next = NULL; 是用于初始化一个新结点,使其 next 指针为空。但在插入操作中,如果 L 不为空,我们不需要这样做,因为 S 的 next 应该指向 L。如果 L 为空(即链表为空),则插入 S 后,S 本身就是新的表头,且其 next 应该已经通过 S->next = NULL;(在插入之前或作为插入过程的一部分)初始化为空,但在这个问题中,我们假设 L 已经存在(即使它可能指向一个空链表,即 L != NULL 但 L->next == NULL),所以我们不需要显式地设置 S->next = NULL。然而,在实际编写代码时,如果创建一个新结点 S,通常会在创建时立即设置其 next 为 NULL,以确保它不会指向任何随机的内存位置。但在这个特定的插入问题中,我们关注的是如何链接到现有的链表,而不是如何初始化新结点。
2. 设栈 S 和队列 Q 的初始状态为空,元素 a、b、c、d、e、f 依次通过栈 S,一个元素出栈后即进入队列 Q。若这 6 个元素出队列的顺序是 b、d、c、f、e、a,则栈 S的容量至少应该是 【】。
答案:3
解析:
元素 a、b、c、d、e、f 依次入栈。当一个元素出栈后,它立即进入队列 Q。出队列的顺序是 b、d、c、f、e、a。
让我们按步骤分析:
a 入栈。
b 入栈。
b 出栈并入队列 Q。此时栈中剩余:a
c 入栈。
d 入栈。
d 出栈并入队列 Q。此时栈中剩余:a,c
c 出栈并入队列 Q。此时栈中剩余:a
到目前为止,出队的顺序是 b、d、c。注意到在 c 出栈之前,栈中最多同时有 3 个元素(a、c、d,在 d 出栈之前)。
e 入栈。此时栈中剩余:a,e
f 入栈。此时栈中剩余:a,e,f(这是栈中的最大容量时刻,因为有 3 个元素同时存在于栈中)
a 出栈并入队列 Q。此时栈中剩余:e,f
e 出栈并入队列 Q。此时栈为空
f 出栈并入队列 Q。此时栈仍然为空
出队的最终顺序是 b、d、c、f、e、a。
在整个过程中,栈中同时存在的最大元素数量是 3(在 f 入栈时)。因此,栈 S 的容量至少应该是 3。
答案是:栈 S 的容量至少应该是 3。
3. 设串 s1='ABCDEFG', s2='PQRST',函数 Concat(x,y)返回 x 串和 y 串的连接串, Substr(s,i,j)返回串 s 从序号 i 开始的 j 个字符组成的子串,Length(s)返回串 s 的长度,则 Concat(Substr(s1,2,Length(s2)),Substr(s1,Length(s2),2))的结果串为【】 。
答案:BCDEFFG
解析:
首先,我们需要明确题目中给出的字符串和函数的定义:
串 s1 = 'ABCDEFG'
串 s2 = 'PQRST'
函数 Concat(x, y) 返回字符串 x 和字符串 y 的连接结果。
函数 Substr(s, i, j) 返回字符串 s 从序号 i 开始的 j 个字符组成的子串。注意,这里的序号通常从 1 开始,且 i 和 j 的取值应确保子串存在。
函数 Length(s) 返回字符串 s 的长度。
接下来,我们根据这些定义来计算表达式 Concat(Substr(s1, 2, Length(s2)), Substr(s1, Length(s2), 2)) 的结果:
计算 Length(s2):
Length(s2) = 5,因为 s2 = 'PQRST',长度为 5。
计算 Substr(s1, 2, Length(s2)):
Substr(s1, 2, 5) = 'BCDEF',因为从 s1 的第 2 个字符开始取 5 个字符。
计算 Substr(s1, Length(s2), 2):
Substr(s1, 5, 2) = 'FG',因为从 s1 的第 5 个字符开始取 2 个字符。
计算 Concat(Substr(s1, 2, Length(s2)), Substr(s1, Length(s2), 2)):
Concat('BCDEF', 'FG') = 'BCDEFFG'。
因此,表达式 Concat(Substr(s1, 2, Length(s2)), Substr(s1, Length(s2), 2)) 的结果串为 'BCDEFFG'。
4. 二维数组 A[10][5]采用行序为主序方式存储,每个元素占 4 个存储单元,并且A[5][3]的存储地址是 1000,则 A[8][2]的地址是 【】。
答案: 1048
解析:
从 A[5][3] 到 A[8][2](包括两端)一共有 0+5+5+3=13 个元素(但注意,我们实际上是从 A[5][3] 开始算的,所以偏移量是基于这个元素的)。然而,由于我们是从 A[5][3] 开始计算,所以真正的"中间"元素数量是 12(如果我们把 A[5][3] 看作是第 0 个元素的话,那么到 A[8][2] 就是第 13 个元素的位置,但我们需要的是偏移量,所以是 12 个元素的偏移)。
每个元素占 4 个存储单元,所以偏移量是:
12×4=48
最后,加上 A[5][3] 的存储地址 1000,得到 A[8][2] 的存储地址:
1000+48=1048
因此,A[8][2] 的地址是 1048。
5. 设广义表 A=(x,((a,b),c,d)),则 Head(Head(Tail(A)))=【】。
答案: (a,b)
解析:
Tail(A):返回广义表 A 去掉第一个元素后的部分。
A = (x,((a,b),c,d))
Tail(A) = (((a,b),c,d))
Head(Tail(A)):返回 Tail(A) 的第一个元素。
Tail(A) = (((a,b),c,d))
Head(Tail(A)) = ((a,b),c,d)
Head(Head(Tail(A))):返回 Head(Tail(A)) 的第一个元素。
Head(Tail(A)) = ((a,b),c,d)
Head(Head(Tail(A))) = (a,b)
因此,Head(Head(Tail(A))) 的结果是 (a,b)
6. 假定一棵树的广义表表示为 A(B(C,D(E,F,G),H(I,J))),则度为3 的结点数有【】个。
答案:2
解析:
树的广义表表示:
在广义表中,圆括号"()"表示一个子树,逗号","用以分隔同一层次的子树或结点。例如,广义表 A(B(C,D(E,F,G),H(I,J))) 可以表示一棵树,其中 A 是根结点,B 是 A 的一个子结点,C,D,H 是 B 的子结点,而 E,F,G 是 D 的子结点,I,J 是 H 的子结点。
树中结点的度:
一个结点的度是指该结点所拥有的子结点的个数。
现在,我们根据给定的广义表 A(B(C,D(E,F,G),H(I,J))) 来分析树的结构,并找出度为3的结点数。
根结点 A 有1个子结点 B,所以 A 的度为1。
结点 B 有3个子结点 C,D,H,所以 B 的度为3。
结点 C 没有子结点,所以 C 的度为0。
结点 D 有3个子结点 E,F,G,所以 D 的度为3。
结点 H 有2个子结点 I,J,所以 H 的度为2。
结点 E,F,G,I,J 都没有子结点,所以它们的度都为0。
综上所述,度为3的结点数有2个,分别是 B 和 D。
7. 具有 n 个结点的二叉树中,有 【】个空指针。
答案:n+1
解析:
在一棵具有 n个结点的二叉树中,空指针的数量为 n+1 个。
因为二叉树中,每个结点最多有两个指针,n个非空结点最多有 2n+1 个非空指针,而二叉树的总结针数为 ,所以空指针的数量为 n+1个。
8. 已知一棵深度为 6 的完全二叉树的第 6 层有 7 个叶子结点,则该完全二叉树总共有【】个叶子结点。
答案:38
解析:
1.深度为6的完全二叉树:
这意味着该二叉树从根节点开始,最多有6层。
2.第6层有7个叶子结点:
在完全二叉树中,叶子节点一定出现在同一层或连续的几层中。
第6层(也就是最后一层)有7个叶子节点,说明这一层不是完全填满的。在满二叉树中,第6层应该有32个节点。但现在只有7个,说明上面的层是完全填满的,直到第5层。
3.计算总结点数:
前5层(包括根节点所在的层)是一个满二叉树,所以前5层的节点总数是 (因为满二叉树的节点数是 2的h次方减一,其中h是高度)。加上第6层的7个节点,总数就是 。
综上所述,这个深度为6且第6层有7个叶子结点的完全二叉树共有38个结点。
9. 设有一个有序文件,各记录的关键字为{2,3,5,7,11,13,17,19,23,29,31,37,41,43,47},当用折半查找算法查找关键字为 7 的记录时,比较次数为【】。
答案:B
解析:
按照折半查找的步骤进行:
初始时,查找范围为整个数组,即下标从0到14(共15个元素)。中间元素的下标为
(0+14)/2 =7,对应的元素是17。因为17大于7,所以继续在左半部分查找。
左半部分的下标范围为0到6(共7个元素)。中间元素的下标为 (0+6)/2 =3,对应的元素是5。因为5小于7,所以继续在右半部分查找。
右半部分(左半部分中的右半部分)的下标范围为4到6。中间元素的下标为
(4+6)/2=5,对应的元素是7。因为7等于要查找的关键字,所以查找成功,比较次数为3次。
因此,当用折半查找算法查找关键字为7的记录时,比较次数为3次。
10. 用【】法构造的哈希函数一定不会发生冲突。
答案:完美哈希函数
解析:
对于给定的固定关键字集合,可以使用完美哈希函数构造法来设计一个哈希函数,该哈希函数在给定集合内保证无冲突。