林老师 · 客观题题库 · 第 19 章 快排与归并 · 知识细节练习

第 19 章 快排与归并 · 知识细节练习

100 题 · 每题对应一个知识细节 · 全部原创
真题
复刻
试卷编号ORIG-第19章快排与归并-知识细节练习
题目总数100 题 · 100 分
试卷类型客观题
考生须知:
① 本卷共 16 大部分,合计 100 题 · 100 分,全部为客观题;
② 试卷右上角设有 「提交答卷」「重置考试」 按钮,提交后系统自动判分并显示答题正确情况,请确认全部作答后再行提交;
③ 试卷不显示答案,提交后方可查看每题作答与正确答案的对照;
④ 答卷进度会保留在本地缓存中,刷新或再次打开仍可继续作答;
⑤ 本卷仅供学生练习使用;请勿用于其他用途;题面有问题请联系:i64coder@163.com。

判 分 报 告

0 / 100 分
0
答 对 · 得 0
0
答 错 · 失 0
当前筛选下没有题目

分治思想

6 QUESTIONS · 2 POINTS EACH
第 1 题 A1 未作答

分治算法的标准三步骤,顺序正确的是?

(1 分)
第 2 题 A2 未作答

判断题:快速排序和归并排序都属于分治算法,但快排的"解决"步骤(分区)做在递归之前,归并的"合并"步骤做在递归之后。

(1 分)
第 3 题 A3 未作答

分治递归必须设置出口(边界条件),快排和归并的出口分别是?

(1 分)
第 4 题 A4 未作答

分治与减治的区别是?

(1 分)
第 5 题 A5 未作答

规模 nn 的问题二分分解为两个 n/2n/2 的子问题,若合并代价为 O(n)O(n),则总复杂度为?

(1 分)
第 6 题 A6 未作答

判断题:分治适用于「子问题互相独立、与原问题同构」的场景;若子问题大量重叠(如朴素递归求斐波那契),直接分治会导致指数级重复计算。

(1 分)

快速排序原理

7 QUESTIONS · 2 POINTS EACH
第 7 题 B1 未作答

快速排序的核心是选择一个基准元素(pivot)。关于基准的选择,下列说法正确的是?

(1 分)
第 8 题 B2 未作答

快速排序的分区(partition)操作完成后,数组的状态是?

(1 分)
第 9 题 B3 未作答

一次分区完成后,基准元素的位置有何特点?

(1 分)
第 10 题 B4 未作答

对区间 [l,r][l, r] 做分区,基准最终落在位置 pp。接下来快排递归处理哪些区间?

(1 分)
第 11 题 B5 未作答

快速排序不稳定的原因是?

(1 分)
第 12 题 B6 未作答

快速排序的平均时间复杂度是?

(1 分)
第 13 题 B7 未作答

判断题:快速排序是原地排序(in-place)——分区只在原数组上交换元素,不需要 O(n)O(n) 级别的辅助数组。

(1 分)

快排复杂度与最坏

7 QUESTIONS · 2 POINTS EACH
第 14 题 C1 未作答

快速排序最坏情况 O(n2)O(n^2) 的典型触发场景是?

(1 分)
第 15 题 C2 未作答

nn 个元素的数组,快排最坏情况下递归深度约为?

(1 分)
第 16 题 C3 未作答

快速排序的最好情况是?

(1 分)
第 17 题 C4 未作答

快速排序的空间复杂度是?(不计原数组本身)

(1 分)
第 18 题 C5 未作答

避免快排最坏情况的常用优化是?

(1 分)
第 19 题 C6 未作答

判断题:快速排序平均复杂度 O(nlogn)O(n \log n) 中的 logn\log n 来自「期望递归层数」,即使某次分区不均衡,期望意义上总的比较次数仍是 O(nlogn)O(n \log n) 级别。

(1 分)
第 20 题 C7 未作答

快排每层分区合计的代价约为 O(n)O(n),若递归层数期望为 log2n\log_2 n,总复杂度约为?

(1 分)

归并排序原理

7 QUESTIONS · 2 POINTS EACH
第 21 题 D1 未作答

归并排序的第一步是?

(1 分)
第 22 题 D2 未作答

归并排序递归到区间长度为 11 时如何处理?

(1 分)
第 23 题 D3 未作答

归并排序的合并步骤:两个有序序列 {1,3,5}\{1, 3, 5\}{2,4,6}\{2, 4, 6\},合并结果的前三个元素依次是?

(1 分)
第 24 题 D4 未作答

归并排序的合并步骤通常需要?

(1 分)
第 25 题 D5 未作答

归并排序稳定的原因是?

(1 分)
第 26 题 D6 未作答

归并排序的最坏时间复杂度是?

(1 分)
第 27 题 D7 未作答

nn 个元素归并排序:递归共 log2n\log_2 n 层,每层合并总代价 O(n)O(n),总复杂度是?

(1 分)

逆序对与归并应用

6 QUESTIONS · 2 POINTS EACH
第 28 题 E1 未作答

序列中「逆序对」的定义是?

(1 分)
第 29 题 E2 未作答

用归并排序求逆序对:合并左右两半时,若右半边元素 aja_j 先于左半边剩余元素被取走,则逆序对计数如何增加?

(1 分)
第 30 题 E3 未作答

判断题:冒泡排序交换相邻元素的次数恰好等于序列的逆序对个数。

(1 分)
第 31 题 E4 未作答

归并排序除排序外,典型应用是?

(1 分)
第 32 题 E5 未作答

需要稳定排序时,归并与快排应如何选择?

(1 分)
第 33 题 E6 未作答

稳定性在多关键字排序中的意义是?

(1 分)

快排归并对比与综合

6 QUESTIONS · 2 POINTS EACH
第 34 题 F1 未作答

关于稳定性,快排与归并的正确对比是?

(1 分)
第 35 题 F2 未作答

关于空间开销,快排与归并的正确对比是?

(1 分)
第 36 题 F3 未作答

关于最坏时间复杂度,快排与归并的正确对比是?

(1 分)
第 37 题 F4 未作答

内存充足、要求排序稳定,且数据规模大——选哪种?

(1 分)
第 38 题 F5 未作答

快排与归并的平均/最坏时间、空间、稳定性的正确总表是?

(1 分)
第 39 题 F6 未作答

判断题:"快排是稳定排序""归并是原地排序"——这两个说法都正确。

(1 分)

分治应用

6 QUESTIONS · 2 POINTS EACH
第 40 题 G1 未作答

二分查找属于分治还是减治?

(1 分)
第 41 题 G2 未作答

快速幂 ana^n 的分治/减治思想是?

(1 分)
第 42 题 G3 未作答

用分治求最大子段和:跨中点的情况如何计算?

(1 分)
第 43 题 G4 未作答

nn 盘汉诺塔,把 n1n-1 个盘从 A 经 C 移到 B、再把最大盘从 A 移到 C、最后把 n1n-1 个盘从 B 经 A 移到 C——该过程的递归次数满足?

(1 分)
第 44 题 G5 未作答

判断题:分治算法自上而下把问题分解再回溯合并,通常用递归实现;递推则自下而上按顺序推算——两者方向相反,但分治的递归树展开后往往也能写成递推(如归并的自底向上迭代版)。

(1 分)
第 45 题 G6 未作答

下列哪个问题也常用分治思想解决?

(1 分)

易错综合

5 QUESTIONS · 2 POINTS EACH
第 46 题 H1 未作答

快排分区代码常写 while (i <= j) 的 i、j 相向扫描。若循环条件误写成 while (i < j),后果是?

(1 分)
第 47 题 H2 未作答

判断题:对已经升序排好的数组用「固定取第一个元素为基准」的快排,时间复杂度约为 O(n2)O(n^2)

(1 分)
第 48 题 H3 未作答

归并合并时,若只判断"左半边取完"而忘了"右半边也取完"(或漏处理某半边剩余元素),后果是?

(1 分)
第 49 题 H4 未作答

判断题:把 a[i] <= a[j] 中的等号错写成 a[i] < a[j](合并相等元素时先取右边),归并排序的稳定性会被破坏。

(1 分)
第 50 题 H5 未作答

判断题:以下结论全部正确——"快排最坏 O(n2)O(n^2) 但平均 O(nlogn)O(n \log n);归并最坏 O(nlogn)O(n \log n) 但需要 O(n)O(n) 辅助空间;两者都是基于比较的排序,比较排序的最优最坏时间复杂度为 O(nlogn)O(n \log n)"。

(1 分)

快排代码阅读

6 QUESTIONS · 2 POINTS EACH
第 51 题 I1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int a[5] = {5, 3, 8, 1, 2};   // 基准 x = a[0] = 5
05    int i = 0, j = 4, x = a[0];
06    while (i <= j) {
07        while (a[i] < x) i++;
08        while (a[j] > x) j--;
09        if (i <= j) { swap(a[i], a[j]); i++; j--; }
10    }
11    for (int k = 0; k < 5; k++) cout << a[k] << " ";
12    return 0;
13}

单选题:程序输出是?

(1 分)
第 52 题 I2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int a[5] = {5, 3, 8, 1, 2};   // 基准 x = a[0] = 5
05    int i = 0, j = 4, x = a[0];
06    while (i <= j) {
07        while (a[i] < x) i++;
08        while (a[j] > x) j--;
09        if (i <= j) { swap(a[i], a[j]); i++; j--; }
10    }
11    for (int k = 0; k < 5; k++) if (a[k] == 5) cout << k;
12    return 0;
13}

单选题:程序输出是?(分区后基准 5 的最终下标)

(1 分)
第 53 题 I3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[3] = {3, 1, 2};
04void qsort(int l, int r) {
05    if (l >= r) return;
06    int x = a[l], i = l, j = r;
07    while (i <= j) {
08        while (a[i] < x) i++;
09        while (a[j] > x) j--;
10        if (i <= j) { swap(a[i], a[j]); i++; j--; }
11    }
12    qsort(l, j);        // 第一次递归
13    qsort(i, r);        // 第二次递归
14}
15int main() { qsort(0, 2); return 0; }

单选题:第一次递归 qsort(l, j) 被调用时,实参是?

(1 分)
第 54 题 I4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[5] = {5, 1, 4, 2, 3};
04void qsort(int l, int r) {
05    if (l >= r) return;
06    int x = a[l], i = l, j = r;
07    while (i <= j) {
08        while (a[i] < x) i++;
09        while (a[j] > x) j--;
10        if (i <= j) { swap(a[i], a[j]); i++; j--; }
11    }
12    qsort(l, j);
13    qsort(i, r);
14}
15int main() {
16    qsort(0, 4);
17    for (int k = 0; k < 5; k++) cout << a[k] << " ";
18    return 0;
19}

单选题:程序输出是?

(1 分)
第 55 题 I5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[3] = {3, 1, 2};
04int cnt = 0;
05void qsort(int l, int r) {
06    if (l >= r) return;
07    int x = a[l], i = l, j = r;
08    while (i <= j) {
09        while (a[i] < x) i++;
10        while (a[j] > x) j--;
11        if (i <= j) { swap(a[i], a[j]); i++; j--; cnt++; }
12    }
13    qsort(l, j);
14    qsort(i, r);
15}
16int main() { qsort(0, 2); cout << cnt; return 0; }

单选题:程序输出是?(对 {3, 1, 2} 快排全程发生的交换次数)

(1 分)
第 56 题 I6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int a[5] = {5, 1, 4, 2, 3};   // 基准 x = a[0] = 5
05    int i = 0, j = 4, x = a[0];
06    while (i <= j) {
07        while (a[i] < x) i++;
08        while (a[j] > x) j--;
09        if (i <= j) { swap(a[i], a[j]); i++; j--; }
10    }
11    cout << i << " " << j;
12    return 0;
13}

单选题:程序输出是?(分区结束后 i 与 j 的值)

(1 分)

快排代码变体

6 QUESTIONS · 2 POINTS EACH
第 57 题 J1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int n = 5, a[5] = {1, 2, 3, 4, 5};
04void qsort(int l, int r) {
05    if (l >= r) return;
06    int p = l + rand() % (r - l + 1);   // 随机选基准
07    swap(a[l], a[p]);                   // 换到区间开头
08    int x = a[l], i = l, j = r;
09    while (i <= j) {
10        while (a[i] < x) i++;
11        while (a[j] > x) j--;
12        if (i <= j) { swap(a[i], a[j]); i++; j--; }
13    }
14    qsort(l, j);
15    qsort(i, r);
16}
17int main() { srand(1); qsort(0, 4); for (int k = 0; k < 5; k++) cout << a[k] << " "; return 0; }

判断题:无论随机基准选中哪个元素,该程序最终都会输出 1 2 3 4 5(已升序序列排序后仍有序),且随机基准使已序输入不再必然触发 O(n2)O(n^2) 最坏情况。

(1 分)
第 58 题 J2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int a[5] = {9, 5, 1, 7, 3};
05    // 三数取中:取 a[0]、a[2](中间)、a[4] 的中位数作基准
06    int x = a[0], y = a[2], z = a[4];
07    int mid = x + y + z - max({x, y, z}) - min({x, y, z});
08    cout << mid;
09    return 0;
10}

单选题:程序输出是?(选出的基准值)

(1 分)
第 59 题 J3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[3] = {3, 1, 2};
04int main() {
05    stack<pair<int, int>> st;      // 用栈模拟递归
06    st.push({0, 2});
07    while (!st.empty()) {
08        int l = st.top().first, r = st.top().second; st.pop();
09        if (l >= r) continue;
10        int x = a[l], i = l, j = r;
11        while (i <= j) {
12            while (a[i] < x) i++;
13            while (a[j] > x) j--;
14            if (i <= j) { swap(a[i], a[j]); i++; j--; }
15        }
16        st.push({i, r});    // 后压右边 → 先处理左边(模拟先左后右递归)
17        st.push({l, j});
18    }
19    for (int k = 0; k < 3; k++) cout << a[k] << " ";
20    return 0;
21}

单选题:程序输出是?

(1 分)
第 60 题 J4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int a[4] = {4, 1, 3, 2};
05    int x = a[0];              // 基准 4,挖坑在下标 0
06    int i = 0, j = 3;
07    while (i < j) {
08        while (i < j && a[j] >= x) j--;
09        if (i < j) { a[i] = a[j]; i++; }   // 右找小填左坑
10        while (i < j && a[i] <= x) i++;
11        if (i < j) { a[j] = a[i]; j--; }   // 左找大填右坑
12    }
13    a[i] = x;                  // 基准回填
14    for (int k = 0; k < 4; k++) cout << a[k] << " ";
15    return 0;
16}

单选题:程序输出是?

(1 分)
第 61 题 J5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int a[5] = {4, 2, 1, 3, 5};    // 基准 = 最后一个元素 5
05    int p = a[4], i = 0;
06    for (int j = 0; j < 4; j++) {
07        if (a[j] < p) { swap(a[i], a[j]); i++; }   // 小元素交换到前缀
08    }
09    swap(a[i], a[4]);              // 基准归位到 i
10    cout << i;
11    return 0;
12}

单选题:程序输出是?(基准 5 落位后的下标)

(1 分)
第 62 题 J6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[4] = {2, 1, 3, 0};
04// Hoare 式分区:返回的分界点 j 满足什么?
05int main() {
06    int x = a[0], i = 0, j = 3;
07    while (i <= j) {
08        while (a[i] < x) i++;
09        while (a[j] > x) j--;
10        if (i <= j) { swap(a[i], a[j]); i++; j--; }
11    }
12    cout << j;
13    return 0;
14}

单选题:程序输出是?且分区结束后 [l,j][l, j][i,r][i, r] 两段的关系是?

(1 分)
拾壹

归并代码阅读

6 QUESTIONS · 2 POINTS EACH
第 63 题 K1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int a[6] = {1, 3, 5, 2, 4, 6};   // 左半 [0,2] 与右半 [3,5] 各自有序
05    int tmp[6];
06    int i = 0, j = 3, k = 0;
07    while (i <= 2 && j <= 5) {
08        if (a[i] <= a[j]) tmp[k++] = a[i++];
09        else tmp[k++] = a[j++];
10    }
11    while (i <= 2) tmp[k++] = a[i++];
12    while (j <= 5) tmp[k++] = a[j++];
13    for (int t = 0; t < 3; t++) cout << tmp[t] << " ";
14    return 0;
15}

单选题:程序输出是?(合并结果的前 3 个元素)

(1 分)
第 64 题 K2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[4] = {3, 1, 4, 2};
04int tmp[4];
05void merge(int l, int m, int r) {
06    int i = l, j = m + 1, k = l;
07    while (i <= m && j <= r) {
08        if (a[i] <= a[j]) tmp[k++] = a[i++];
09        else tmp[k++] = a[j++];
10    }
11    while (i <= m) tmp[k++] = a[i++];
12    while (j <= r) tmp[k++] = a[j++];
13    for (int t = l; t <= r; t++) a[t] = tmp[t];
14}
15void msort(int l, int r) {
16    if (l >= r) return;
17    int m = (l + r) / 2;
18    msort(l, m);
19    msort(m + 1, r);
20    merge(l, m, r);
21}
22int main() {
23    msort(0, 3);
24    for (int k = 0; k < 4; k++) cout << a[k] << " ";
25    return 0;
26}

单选题:程序输出是?

(1 分)
第 65 题 K3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[4] = {3, 1, 4, 2};
04int tmp[4];
05void merge(int l, int m, int r) {
06    cout << l << m << r << " ";    // 打印每次合并的区间端点
07    int i = l, j = m + 1, k = l;
08    while (i <= m && j <= r) {
09        if (a[i] <= a[j]) tmp[k++] = a[i++];
10        else tmp[k++] = a[j++];
11    }
12    while (i <= m) tmp[k++] = a[i++];
13    while (j <= r) tmp[k++] = a[j++];
14    for (int t = l; t <= r; t++) a[t] = tmp[t];
15}
16void msort(int l, int r) {
17    if (l >= r) return;
18    int m = (l + r) / 2;
19    msort(l, m);
20    msort(m + 1, r);
21    merge(l, m, r);
22}
23int main() { msort(0, 3); return 0; }

单选题:程序输出是?(merge 被调用的区间端点序列,每次打印 l、m、r 三个数)

(1 分)
第 66 题 K4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[4] = {1, 2, 3, 4};
04int tmp[4];
05void merge(int l, int m, int r) {
06    int i = l, j = m + 1, k = l;
07    while (i <= m && j <= r) {
08        if (a[i] <= a[j]) tmp[k++] = a[i++];
09        else tmp[k++] = a[j++];
10    }
11    while (i <= m) tmp[k++] = a[i++];
12    while (j <= r) tmp[k++] = a[j++];
13    for (int t = l; t <= r; t++) a[t] = tmp[t];
14}
15int main() {
16    merge(0, 1, 3);       // 直接合并 [0,1] 与 [2,3] 两段(各自有序)
17    for (int k = 0; k < 4; k++) cout << a[k] << " ";
18    return 0;
19}

单选题:程序输出是?

(1 分)
第 67 题 K5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[4] = {2, 1, 4, 3};
04int tmp[4];
05int cnt = 0;
06void merge(int l, int m, int r) {
07    int i = l, j = m + 1, k = l;
08    while (i <= m && j <= r) {
09        cnt++;                       // 每次比较计数
10        if (a[i] <= a[j]) tmp[k++] = a[i++];
11        else tmp[k++] = a[j++];
12    }
13    while (i <= m) tmp[k++] = a[i++];
14    while (j <= r) tmp[k++] = a[j++];
15    for (int t = l; t <= r; t++) a[t] = tmp[t];
16}
17void msort(int l, int r) {
18    if (l >= r) return;
19    int m = (l + r) / 2;
20    msort(l, m);
21    msort(m + 1, r);
22    merge(l, m, r);
23}
24int main() { msort(0, 3); cout << cnt; return 0; }

单选题:程序输出是?(归并全程的比较次数)

(1 分)
第 68 题 K6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int a[4] = {3, 1, 4, 2};
05    // 自底向上归并:第一轮步长 len = 1,相邻单个元素两两合并
06    int len = 1;
07    for (int s = 0; s + len < 4; s += 2 * len) {
08        if (a[s] > a[s + len]) swap(a[s], a[s + len]);
09    }
10    for (int k = 0; k < 4; k++) cout << a[k] << " ";
11    return 0;
12}

单选题:程序输出是?(第一轮合并后的数组)

(1 分)
拾贰

归并代码完善与逆序对

6 QUESTIONS · 2 POINTS EACH
第 69 题 L1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[4] = {1, 3, 2, 4};
04int tmp[4];
05void merge(int l, int m, int r) {
06    int i = l, j = m + 1, k = l;
07    while (i <= m && j <= r) {
08        if (______) tmp[k++] = a[i++];   // 先取左边 → 保持稳定性
09        else tmp[k++] = a[j++];
10    }
11    while (i <= m) tmp[k++] = a[i++];
12    while (j <= r) tmp[k++] = a[j++];
13    for (int t = l; t <= r; t++) a[t] = tmp[t];
14}
15int main() { merge(0, 1, 3); for (int k = 0; k < 4; k++) cout << a[k] << " "; return 0; }

单选题:横线处应填入?(使输出为 1 2 3 4 且保持稳定性)

(1 分)
第 70 题 L2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[3] = {3, 1, 2};
04int tmp[3];
05long long cnt = 0;
06void merge(int l, int m, int r) {
07    int i = l, j = m + 1, k = l;
08    while (i <= m && j <= r) {
09        if (a[i] <= a[j]) tmp[k++] = a[i++];
10        else { cnt += (m - i + 1); tmp[k++] = a[j++]; }   // 右元素先取 → 左剩余全构成逆序对
11    }
12    while (i <= m) tmp[k++] = a[i++];
13    while (j <= r) tmp[k++] = a[j++];
14    for (int t = l; t <= r; t++) a[t] = tmp[t];
15}
16void msort(int l, int r) {
17    if (l >= r) return;
18    int m = (l + r) / 2;
19    msort(l, m);
20    msort(m + 1, r);
21    merge(l, m, r);
22}
23int main() { msort(0, 2); cout << cnt; return 0; }

单选题:程序输出是?(序列 {3, 1, 2} 的逆序对个数)

(1 分)
第 71 题 L3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[4] = {4, 3, 2, 1};
04int tmp[4];
05long long cnt = 0;
06void merge(int l, int m, int r) {
07    int i = l, j = m + 1, k = l;
08    while (i <= m && j <= r) {
09        if (a[i] <= a[j]) tmp[k++] = a[i++];
10        else { ______; tmp[k++] = a[j++]; }   // 累计左半边剩余元素个数
11    }
12    while (i <= m) tmp[k++] = a[i++];
13    while (j <= r) tmp[k++] = a[j++];
14    for (int t = l; t <= r; t++) a[t] = tmp[t];
15}
16void msort(int l, int r) {
17    if (l >= r) return;
18    int m = (l + r) / 2;
19    msort(l, m);
20    msort(m + 1, r);
21    merge(l, m, r);
22}
23int main() { msort(0, 3); cout << cnt; return 0; }

单选题:横线处应填入?(使输出为 6——完全逆序序列的逆序对个数)

(1 分)
第 72 题 L4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03struct Node { int v; Node* nxt; };
04int main() {
05    // 链表 A: 1 -> 3 -> NULL,链表 B: 2 -> 4 -> NULL
06    Node a2 = {3, nullptr}, a1 = {1, &a2};
07    Node b2 = {4, nullptr}, b1 = {2, &b2};
08    Node *p = &a1, *q = &b1;
09    Node head = {0, nullptr}, *t = &head;
10    while (p && q) {                       // 归并两个有序链表
11        if (p->v <= q->v) { t->nxt = p; p = p->nxt; }
12        else { t->nxt = q; q = q->nxt; }
13        t = t->nxt;
14    }
15    t->nxt = p ? p : q;
16    for (Node* c = head.nxt; c; c = c->nxt) cout << c->v << " ";
17    return 0;
18}

单选题:程序输出是?

(1 分)
第 73 题 L5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[4] = {3, 1, 4, 2};
04int tmp[4];
05int main() {
06    // 自底向上归并:步长从 1 开始逐轮翻倍
07    for (int len = ______; len < 4; len *= 2) {
08        for (int s = 0; s < 4; s += 2 * len) {
09            int m = min(s + len - 1, 3), r = min(s + 2 * len - 1, 3);
10            int i = s, j = m + 1, k = s;
11            while (i <= m && j <= r) {
12                if (a[i] <= a[j]) tmp[k++] = a[i++];
13                else tmp[k++] = a[j++];
14            }
15            while (i <= m) tmp[k++] = a[i++];
16            while (j <= r) tmp[k++] = a[j++];
17            for (int t = s; t <= r; t++) a[t] = tmp[t];
18        }
19    }
20    for (int k = 0; k < 4; k++) cout << a[k] << " ";
21    return 0;
22}

单选题:横线处应填入?(使输出为 1 2 3 4

(1 分)
第 74 题 L6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03struct P { int v; char tag; };
04P a[4] = {{2, 'a'}, {1, 'b'}, {2, 'c'}, {1, 'd'}};
05P tmp[4];
06void merge(int l, int m, int r) {
07    int i = l, j = m + 1, k = l;
08    while (i <= m && j <= r) {
09        if (a[i].v <= a[j].v) tmp[k++] = a[i++];   // 相等先取左 → 稳定
10        else tmp[k++] = a[j++];
11    }
12    while (i <= m) tmp[k++] = a[i++];
13    while (j <= r) tmp[k++] = a[j++];
14    for (int t = l; t <= r; t++) a[t] = tmp[t];
15}
16void msort(int l, int r) {
17    if (l >= r) return;
18    int m = (l + r) / 2;
19    msort(l, m);
20    msort(m + 1, r);
21    merge(l, m, r);
22}
23int main() {
24    msort(0, 3);
25    for (int k = 0; k < 4; k++) cout << a[k].v << a[k].tag << " ";
26    return 0;
27}

单选题:程序输出是?

(1 分)
拾叁

对比与代码实测

6 QUESTIONS · 2 POINTS EACH
第 75 题 M1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[5] = {1, 2, 3, 4, 5};     // 已升序
04void qsort(int l, int r) {
05    if (l >= r) return;
06    int x = a[l], i = l, j = r;  // 固定取首元素为基准
07    while (i <= j) {
08        while (a[i] < x) i++;
09        while (a[j] > x) j--;
10        if (i <= j) { swap(a[i], a[j]); i++; j--; }
11    }
12    qsort(l, j);
13    qsort(i, r);
14}
15int main() { qsort(0, 4); return 0; }

判断题:对已升序数组 {1,2,3,4,5} 使用「固定取首元素为基准」的快排,其时间复杂度约为 O(n2)O(n^2)——这是快排最坏情况的典型触发方式。

(1 分)
第 76 题 M2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03struct P { int v; char tag; };
04P a[4] = {{1, 'x'}, {2, 'a'}, {2, 'b'}, {3, 'y'}};
05int main() {
06    // 用不稳定的分区方式处理:相等元素跨越交换
07    int i = 0, j = 3, x = a[2].v;   // 基准取 a[2].v = 2
08    while (i <= j) {
09        while (a[i].v < x) i++;
10        while (a[j].v > x) j--;
11        if (i <= j) { swap(a[i], a[j]); i++; j--; }
12    }
13    for (int k = 0; k < 4; k++) cout << a[k].v << a[k].tag << " ";
14    return 0;
15}

单选题:程序输出是?(观察值相同的 2a2b 的相对顺序)

(1 分)
第 77 题 M3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[5] = {1, 2, 3, 4, 5};
04int dep = 0, mx = 0;
05void qsort(int l, int r) {
06    if (l >= r) return;
07    dep++;
08    mx = max(mx, dep);
09    int x = a[l], i = l, j = r;
10    while (i <= j) {
11        while (a[i] < x) i++;
12        while (a[j] > x) j--;
13        if (i <= j) { swap(a[i], a[j]); i++; j--; }
14    }
15    qsort(l, j);
16    qsort(i, r);
17    dep--;
18}
19int main() { qsort(0, 4); cout << mx; return 0; }

单选题:程序输出是?(对已升序数组、固定首元素基准的快排,最大递归深度;dep++ 只对真正进入分区的调用计数,叶子出口不计)

(1 分)
第 78 题 M4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03// 固定取首元素为基准的快排(省略函数体,行为与前述一致)
04void qsort(int l, int r);

单选题:下列哪个输入对「固定取首元素为基准」的快排而言最接近最坏情况 O(n2)O(n^2)

(1 分)
第 79 题 M5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int n = 1000000;
05    // 排序算法 A 需要数组: int tmp[n]
06    // 排序算法 B 只需要几个变量(原地交换)
07    cout << "A 空间 O(n),B 空间 O(log n)";
08    return 0;
09}

判断题:算法 A 是归并排序(辅助数组 O(n)O(n)),算法 B 是快速排序(递归栈 O(logn)O(\log n))——该描述正确。

(1 分)
第 80 题 M6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[6] = {5, 2, 4, 1, 3, 0};
04void qsort(int l, int r) {
05    if (r - l + 1 <= 3) {          // 小规模改用插入排序
06        for (int i = l + 1; i <= r; i++) {
07            int t = a[i], j = i - 1;
08            while (j >= l && a[j] > t) { a[j + 1] = a[j]; j--; }
09            a[j + 1] = t;
10        }
11        return;
12    }
13    int x = a[l], i = l, j = r;
14    while (i <= j) {
15        while (a[i] < x) i++;
16        while (a[j] > x) j--;
17        if (i <= j) { swap(a[i], a[j]); i++; j--; }
18    }
19    qsort(l, j);
20    qsort(i, r);
21}
22int main() { qsort(0, 5); for (int k = 0; k < 6; k++) cout << a[k] << " "; return 0; }

单选题:程序输出是?

(1 分)
拾肆

分治应用代码

6 QUESTIONS · 2 POINTS EACH
第 81 题 N1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int main() {
04    int a[5] = {1, 3, 5, 7, 9};
05    int l = 0, r = 4, x = 7, ans = -1;
06    while (l <= r) {
07        int m = (l + r) / 2;
08        if (a[m] == x) { ans = m; break; }
09        else if (a[m] < x) l = m + 1;
10        else r = m - 1;
11    }
12    cout << ans;
13    return 0;
14}

单选题:程序输出是?

(1 分)
第 82 题 N2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03long long qpow(long long a, long long n) {
04    long long r = 1;
05    while (n) {
06        if (n & 1) r = r * a;      // 二进制位为 1 时乘入
07        a = a * a;                 // 底数平方
08        n >>= 1;                   // 指数右移
09    }
10    return r;
11}
12int main() { cout << qpow(2, 10); return 0; }

单选题:程序输出是?

(1 分)
第 83 题 N3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[9] = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
04// 分治求最大子段和:左半最大 / 右半最大 / 跨中点最大 三者取大
05int solve(int l, int r) {
06    if (l == r) return a[l];
07    int m = (l + r) / 2;
08    int lm = solve(l, m), rm = solve(m + 1, r);       // 左右子问题
09    int lsum = -1e9, s = 0;
10    for (int i = m; i >= l; i--) { s += a[i]; lsum = max(lsum, s); }   // 跨中点左后缀
11    int rsum = -1e9; s = 0;
12    for (int i = m + 1; i <= r; i++) { s += a[i]; rsum = max(rsum, s); }  // 跨中点右前缀
13    return max({lm, rm, lsum + rsum});
14}
15int main() { cout << solve(0, 8); return 0; }

单选题:程序输出是?

(1 分)
第 84 题 N4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03void hanoi(int n, char a, char b, char c) {   // n 盘:a 经 b 移到 c
04    if (n == 0) return;
05    hanoi(n - 1, a, c, b);
06    cout << a << "->" << c << " ";
07    hanoi(n - 1, b, a, c);
08}
09int main() { hanoi(2, 'A', 'B', 'C'); return 0; }

单选题:程序输出是?(2 个盘的最优移动序列)

(1 分)
第 85 题 N5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03long long qpow(long long a, long long n, long long p) {
04    long long r = 1;
05    a %= p;
06    while (n) {
07        if (n & 1) r = r * a % p;
08        a = a * a % p;
09        n >>= 1;
10    }
11    return r;
12}
13int main() { cout << qpow(2, 10, 1000); return 0; }

单选题:程序输出是?

(1 分)
第 86 题 N6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[5] = {1, 2, 3, 4, 5};
04int sum(int l, int r) {
05    if (l == r) return a[l];
06    int m = (l + r) / 2;
07    return sum(l, m) + sum(m + 1, r);
08}
09int main() { cout << sum(0, 4); return 0; }

单选题:程序输出是?

(1 分)
拾伍

完善程序

7 QUESTIONS · 2 POINTS EACH
第 87 题 O1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[5] = {4, 2, 5, 1, 3};
04void qsort(int l, int r) {
05    if (l >= r) return;
06    int x = a[l], i = l, j = r;
07    while (______) {              // 相向扫描循环条件
08        while (a[i] < x) i++;
09        while (a[j] > x) j--;
10        if (i <= j) { swap(a[i], a[j]); i++; j--; }
11    }
12    qsort(l, j);
13    qsort(i, r);
14}
15int main() { qsort(0, 4); for (int k = 0; k < 5; k++) cout << a[k] << " "; return 0; }

单选题:横线处应填入?(使输出为 1 2 3 4 5

(1 分)
第 88 题 O2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[5] = {4, 2, 5, 1, 3};
04void qsort(int l, int r) {
05    if (l >= r) return;
06    int x = a[l], i = l, j = r;
07    while (i <= j) {
08        while (a[i] < x) i++;
09        while (a[j] > x) j--;
10        if (i <= j) { swap(a[i], a[j]); i++; j--; }
11    }
12    ______;              // 左段递归
13    qsort(i, r);         // 右段递归
14}
15int main() { qsort(0, 4); for (int k = 0; k < 5; k++) cout << a[k] << " "; return 0; }

单选题:横线处应填入?(分区结束后 i > j,两段为 [l, j] 与 [i, r])

(1 分)
第 89 题 O3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[4] = {1, 3, 2, 4};
04int tmp[4];
05void merge(int l, int m, int r) {
06    int i = l, j = m + 1, k = l;
07    while (i <= m && j <= r) {
08        if (a[i] <= a[j]) tmp[k++] = a[i++];
09        else tmp[k++] = a[j++];
10    }
11    while (______) tmp[k++] = a[i++];    // 左半边剩余
12    while (j <= r) tmp[k++] = a[j++];    // 右半边剩余
13    for (int t = l; t <= r; t++) a[t] = tmp[t];
14}
15int main() { merge(0, 1, 3); for (int k = 0; k < 4; k++) cout << a[k] << " "; return 0; }

单选题:横线处应填入?(使输出为 1 2 3 4

(1 分)
第 90 题 O4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[4] = {3, 1, 4, 2};
04int tmp[4];
05void merge(int l, int m, int r) {
06    int i = l, j = m + 1, k = l;
07    while (i <= m && j <= r) {
08        if (a[i] <= a[j]) tmp[k++] = a[i++];
09        else tmp[k++] = a[j++];
10    }
11    while (i <= m) tmp[k++] = a[i++];
12    while (j <= r) tmp[k++] = a[j++];
13    for (int t = l; t <= r; t++) a[t] = tmp[t];
14}
15void msort(int l, int r) {
16    if (l >= r) return;
17    int m = (l + r) / 2;
18    ______;              // 递归左半
19    msort(m + 1, r);     // 递归右半
20    merge(l, m, r);
21}
22int main() { msort(0, 3); for (int k = 0; k < 4; k++) cout << a[k] << " "; return 0; }

单选题:横线处应填入?(使输出为 1 2 3 4

(1 分)
第 91 题 O5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[4] = {2, 4, 1, 3};
04int tmp[4];
05long long cnt = 0;
06void merge(int l, int m, int r) {
07    int i = l, j = m + 1, k = l;
08    while (i <= m && j <= r) {
09        if (a[i] <= a[j]) tmp[k++] = a[i++];
10        else { ______; tmp[k++] = a[j++]; }   // 累计逆序对
11    }
12    while (i <= m) tmp[k++] = a[i++];
13    while (j <= r) tmp[k++] = a[j++];
14    for (int t = l; t <= r; t++) a[t] = tmp[t];
15}
16void msort(int l, int r) {
17    if (l >= r) return;
18    int m = (l + r) / 2;
19    msort(l, m);
20    msort(m + 1, r);
21    merge(l, m, r);
22}
23int main() { msort(0, 3); cout << cnt; return 0; }

单选题:横线处应填入?(使输出为 3——序列 {2, 4, 1, 3} 的逆序对个数)

(1 分)
第 92 题 O6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03long long qpow(long long a, long long n) {
04    long long r = 1;
05    while (n) {
06        if (______) r = r * a;     // 当前二进制位为 1 时乘入
07        a = a * a;
08        n >>= 1;
09    }
10    return r;
11}
12int main() { cout << qpow(3, 4); return 0; }

单选题:横线处应填入?(使输出为 81

(1 分)
第 93 题 O7 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[5] = {9, 1, 5, 7, 3};
04int main() {
05    int l = 0, r = 4;
06    int m = (l + r) / 2;
07    // 三数取中:把 a[l]、a[m]、a[r] 的中位数换到 a[l] 作基准
08    if (a[l] > a[m]) swap(a[l], a[m]);
09    if (______) swap(a[l], a[r]);
10    if (a[m] > a[r]) swap(a[m], a[r]);
11    swap(a[l], a[m]);          // 中位数换到开头
12    cout << a[0];
13    return 0;
14}

单选题:横线处应填入?(使输出为基准值 5——首 9、中 5、尾 3 的中位数)

(1 分)
拾陆

代码易错

7 QUESTIONS · 2 POINTS EACH
第 94 题 P1 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[3] = {2, 3, 1};
04int main() {
05    int x = a[0], i = 0, j = 2;
06    while (i < j) {                  // 错误:应 i <= j
07        while (a[i] < x) i++;
08        while (a[j] > x) j--;
09        if (i <= j) { swap(a[i], a[j]); i++; j--; }
10    }
11    for (int k = 0; k < 3; k++) cout << a[k] << " ";
12    return 0;
13}

单选题:程序输出是?(分区后数组状态)

(1 分)
第 95 题 P2 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[4] = {2, 1, 3, 4};
04void qsort(int l, int r) {
05    if (l > r) return;               // 出口用 l > r
06    int x = a[l], i = l, j = r;
07    while (i <= j) {
08        while (a[i] < x) i++;
09        while (a[j] > x) j--;
10        if (i <= j) { swap(a[i], a[j]); i++; j--; }
11    }
12    qsort(l, r);                     // 错误:递归区间未缩小
13}
14int main() { qsort(0, 3); cout << "run"; return 0; }

单选题:程序会发生什么?(递归调用 qsort(l, r) 参数与入口完全相同)

(1 分)
第 96 题 P3 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[4] = {5, 6, 1, 3};
04int tmp[4];
05void merge(int l, int m, int r) {
06    int i = l, j = m + 1, k = l;
07    while (i <= m && j <= r) {
08        if (a[i] <= a[j]) tmp[k++] = a[i++];
09        else tmp[k++] = a[j++];
10    }
11    // 错误:少了两个 while——左/右剩余元素未搬入
12    for (int t = l; t <= r; t++) a[t] = tmp[t];
13}
14int main() { merge(0, 1, 3); for (int k = 0; k < 4; k++) cout << a[k] << " "; return 0; }

单选题:程序输出是?(tmp 未初始化的位置值不确定,此处按常见编译器默认 0 计)

(1 分)
第 97 题 P4 未作答

01#include <bits/stdc++.h>
02using namespace std;
03struct P { int v; char tag; };
04P a[4] = {{1, 'b'}, {1, 'd'}, {2, 'a'}, {2, 'c'}};
05P tmp[4];
06void merge(int l, int m, int r) {
07    int i = l, j = m + 1, k = l;
08    while (i <= m && j <= r) {
09        if (a[i].v < a[j].v) tmp[k++] = a[i++];   // 错误:相等时先取右边
10        else tmp[k++] = a[j++];
11    }
12    while (i <= m) tmp[k++] = a[i++];
13    while (j <= r) tmp[k++] = a[j++];
14    for (int t = l; t <= r; t++) a[t] = tmp[t];
15}
16void msort(int l, int r) {
17    if (l >= r) return;
18    int m = (l + r) / 2;
19    msort(l, m);
20    msort(m + 1, r);
21    merge(l, m, r);
22}
23int main() {
24    msort(0, 3);
25    for (int k = 0; k < 4; k++) cout << a[k].v << a[k].tag << " ";
26    return 0;
27}

单选题:程序输出是?(观察值相同的元素相对顺序是否被破坏)

(1 分)
第 98 题 P5 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[3] = {3, 1, 2};
04void qsort(int l, int r) {
05    // 错误:没有 if (l >= r) return; 出口
06    int x = a[l], i = l, j = r;
07    while (i <= j) {
08        while (a[i] < x) i++;
09        while (a[j] > x) j--;
10        if (i <= j) { swap(a[i], a[j]); i++; j--; }
11    }
12    qsort(l, j);
13    qsort(i, r);
14}
15int main() { qsort(0, 2); return 0; }

判断题:缺少 if (l >= r) return 出口,当递归到区间长度 1\le 1 时仍会继续递归,最终导致栈溢出——该说法正确。

(1 分)
第 99 题 P6 未作答

01#include <bits/stdc++.h>
02using namespace std;
03int a[4] = {1, 2, 3, 4};        // 已升序
04int calls = 0;
05void qsort(int l, int r) {
06    calls++;                     // 统计调用次数(含出口判断)
07    if (l >= r) return;
08    int x = a[l], i = l, j = r;  // 固定取首元素为基准
09    while (i <= j) {
10        while (a[i] < x) i++;
11        while (a[j] > x) j--;
12        if (i <= j) { swap(a[i], a[j]); i++; j--; }
13    }
14    qsort(l, j);
15    qsort(i, r);
16}
17int main() { qsort(0, 3); cout << calls; return 0; }

单选题:程序输出是?(总调用次数 = 内部节点数 + 叶子出口判断数)

(1 分)
第 100 题 P7 未作答

判断题:以下结论全部正确——"快排分区后基准落位,递归只处理 [l, j][i, r] 两段(基准不参与);归并先递归两半再合并,需要 O(n)O(n) 辅助数组;逆序对计数在合并右元素先取时加左剩余个数;快速幂每次把指数折半,复杂度 O(logn)O(\log n)"。

(1 分)