下⾯关于C++中形参、实参和定义域的说法中,正确的⼀项是( )。
A:形参是函数定义时声明的局部变量,只在函数内部有效;常量引用不可修改,实参形参类型可隐式转换,对指针赋值不影响实参;B 中常量引用不可修改,D 中指针赋值只改形参本身。
已知三个序列:s1={3,1,8,2,5,6,7,4},s2={1,5,1,8,6,4,7,5,6},s3={1,8,3,5,7,6,2,4}。以下哪个序列是它们的最长公共子序列()。
A:{1,8,5,6} 在三个序列中都按下标递增出现且长度 4;B 中 7 在 s3 里位于 6 之前、D 中 4 在 s2 里位于 7 之前,均不成立。
现有一个地址区间为 的哈希表,当出现冲突情况,会往后找第一个空的地址存储(到 冲突了就从 开始往后),现在要依次存储 ,哈希函数为 。其中 存储在哈希表哪个地址中( )。
D:1 存 2 号、3 存 1 号、5 存 8 号、7 探测 1、2 后存 3 号;9 的 h(9)=(81+9)%11=2,线性探测 2、3 均占用,落到 4 号。
在 背包问题中,给定一组物品,每个物品有一个重量和价值,背包的容量有限。假设背包的最大容量为 ,物品的数量为 ,其中第 个物品的重量为 ,价值为 。以下关于 背包问题的描述,正确的是()。
C:0/1 背包 DP 空间 O(nW),因每件物品只依赖上一件,可用滚动数组压到 O(W);贪心不保证最优,且需容量倒序枚举,故选 C。
⼀棵深度为 (根节点深度为 )的完全⼆叉树,节点总数最少有( )。
B:深度 6 的完全二叉树最少:前 5 层满共 2⁵−1=31 个结点,再加第 6 层 1 个,共 32 个;第 6 层只需 1 个结点即可称为深度 6 的完全二叉树。
对于如下二叉树,下面关于访问的顺序说法错误的是( )。
D:树为 A(B(D,E), C(F,G(H,I(J)))),中序应为 D B E A F C H G I J,D 写成 …G J I 顺序颠倒故错误;A、B、C 均正确。
下面程序的运行结果为( )。
01++ 02#include <iostream> 03 04int query(int n, int *a, int x) { 05 int l = 0, r = n; 06 while (l < r) { 07 int mid = l + (r - l) / 2; 08 if (a[mid] >= x) r = mid; 09 else l = mid + 1; 10 } 11 12 if (l == n) return -1; 13 return l; 14} 15 16int main() { 17 int n = 10; 18 int x = 3; 19 int num[] = {1, 2, 2, 3, 3, 4, 5, 5, 6, 7}; 20 21 std::cout << query(n, num, x) << "\n"; 22 return 0; 23}
B:query 是二分查找第一个 ≥ x 的位置:a[mid]>=3 时 r=mid,否则 l=mid+1,num 中第一个 ≥3 的下标是 3(num[3]=3)。
下面程序中,函数 query 的时间复杂度是( )。
01++ 02#include <iostream> 03 04int query(int n, int *a, int x) { 05 int l = 0, r = n; 06 while (l < r) { 07 int mid = l + (r - l) / 2; 08 if (a[mid] >= x) r = mid; 09 else l = mid + 1; 10 } 11 12 if (l == n) return -1; 13 return l; 14} 15 16int main() { 17 int n = 10; 18 int x = 3; 19 int num[] = {1, 2, 2, 3, 3, 4, 5, 5, 6, 7}; 20 21 std::cout << query(n, num, x) << "\n"; 22 return 0; 23}
B:query 是二分查找,每轮把搜索区间减半,最多 log₂n 次迭代,时间复杂度 O(log n);log 底数为 2 时即折半次数。
有 个字符,它们出现的次数分别为 次、 次、 次、 次、 次。现在要⽤哈夫曼编码的⽅式来为这些字符进⾏编码,最⼩加权路径长度 (每个字符的出现次数 它的编码长度,再把每个字符结果加起来)的值为( )。
B:哈夫曼合并:2+2=4、3+3=6、4+5=9、6+9=15,WPL=内部结点权值和=4+6+9+15=34;WPL 也可用叶子权值乘以路径长度求和验证。
下⾯程序的运⾏结果为( )。
01++ 02#include <iostream> 03using namespace std; 04int f(int n) { 05 if (n <= 2) return n * 2; 06 return f(n - 1) + f(n - 2); 07} 08int main() { 09 cout << f(5) << endl; 10 return 0; 11}
B:f(1)=2、f(2)=4,f(3)=f(2)+f(1)=6,f(4)=f(3)+f(2)=10,f(5)=f(4)+f(3)=16。
⼀个简单⽆向图 有 条边,且每个顶点的度数都为 ,则图 的顶点个数为( )。
C:每点度数均为 4,由度数和等于 2 倍边数得 4V=2×36=72,故顶点数 V=18;由握手引理:度数和等于 2 倍边数,故选 C。
下⾯关于⼆叉树的说法正确的是( )。
C:n 结点二叉树高度满足 ⌈log₂(n+1)⌉≤h≤n(完全/满二叉树最小,退化链最大);单结点树先序中序相同、先序+后序不能唯一确定、根后不一定是左孩子。
假设⼀个算法时间复杂度的递推式是 ( 为正整数),和 ,那么这个算法的时间复杂度是( )。
B:T(n)=8T(n/4)+n√n,a=8、b=4,log₄8=1.5=n√n 的指数,主定理情形二得 O(n√n·log n)。
下⾯哪⼀个可能是下图的深度优先遍历序列( )。
B:B 的深搜 1→5→8→9,回溯到 8 访问 7,再回溯到 1 访问 4,最后从未访问的 6 出发走 3、2;A 在 6 后应访 9 而非 8,C、D 也有类似跳步错误。
下⾯这个有向图的强连通分量的个数是( )。
C:强连通分量按双向可达划分:{1,2}、{4,5,7,8}、{6,9,10,11} 三个环块,加上孤立点 3 与 12,共 5 个。
C++语⾔中,表达式 3 ^ 2 的结果类型为 int,值为 9。
错。^ 是按位异或:3^2 = 011₂ XOR 010₂ = 001₂ = 1,不是 9;乘方需用 pow;乘方运算在 C++ 中没有专用运算符。
使⽤ cmath 头⽂件中的正弦函数,表达式 sin(90) 的结果类型为 double,值约为 。
错。sin 的参数是弧度制:sin(90) 求 90 弧度的正弦约 0.894,不是 sin90°=1.0,需转弧度;如需按角度计算需先乘 π/180 转弧度。
使⽤ strcmp("10", "9") ⽐较两个字符串,返回值⼤于 ,说明 "10" ⽐ "9" ⼤。
错。strcmp 按字符 ASCII 逐位比较:「10」首字符 1(49) 小于 「9」的 9(57),故 strcmp(10,9) 返回负值,说明 10 比 9 小,不是大于 0。
选择排序是⼀种不稳定的排序算法,⽽冒泡排序是⼀种稳定的排序算法。
对。选择排序交换最小值时可能改变相等元素顺序故不稳定;冒泡只交换相邻逆序元素故稳定;稳定性是排序算法的重要性质;两者稳定性相反。
求两个长度为 序列的最长公共⼦序列(LCS)长度时,可以使⽤滚动数组将空间复杂度从 优化到 。
对。LCS 的 dp[i][j] 只依赖上一行,用两行滚动数组即可把空间从 O(n²) 优化到 O(n);滚动数组只保留上一行,当前行可覆盖。
在⽆向图中,所有顶点的度数之和等于边数的两倍。
对。无向图中每条边给两个端点的度各贡献 1,故所有顶点度数之和等于边数的两倍;这是握手引理在图论中的直接应用;该性质对任何无向图均成立。
使⽤邻接矩阵存储⼀个有 个顶点、 条边的图,对该图进⾏⼀次完整的 遍历,时间复杂度为 。
错。邻接矩阵存图时 BFS 判断相邻要扫整行,复杂度 O(V²),不是 O(V+E);O(V+E) 是邻接表的复杂度;故用邻接矩阵做 BFS 应为 O(V²)。
在图像处理或游戏开发中,泛洪(flood fill)算法既可以⽤BFS实现,也可以⽤DFS实现。
对。泛洪填充既可用 BFS(队列)实现,也可用 DFS(递归或显式栈)实现,两种方式都可行;用栈或队列实现均可,取决于实现方式,故对。
使⽤链地址法处理冲突的哈希表,当所有元素都映射到同⼀个槽位时,查找操作的最坏时间复杂度为 ,其中 为元素个数。
对。链地址法若所有元素映射到同一槽位,查找需顺序扫描该链上的 n 个元素,最坏为 O(n);此时哈希表退化为链表查找,故对。
⼀个包含 个顶点的连通⽆向图,其任何⼀棵⽣成树都恰好包含 条边。
对。V 个顶点的连通无向图,任何生成树都是连通的极小无环子图,恰好包含 V−1 条边;生成树是边数最少的连通子图;生成树不唯一但边数固定为 V−1。