林老师 · 客观题题库 · 第 7 章 链表 · 知识细节练习

第 7 章 链表 · 知识细节练习

100 题 · 每题对应一个知识细节 · 全部原创
真题
复刻
试卷编号ORIG-第7章链表-知识细节练习
题目总数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 未作答

判断题:单向链表最后一个节点的 next 指针指向空(nullptr)。

(1 分)
第 6 题 A6 未作答

判断题:判断单向链表是否为空,只需看头指针是否为 nullptr

(1 分)

单向链表操作

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

判断题:遍历单向链表时,从 head 出发,沿 next 指针逐个访问,直到 nullptr 为止。

(1 分)
第 8 题 B2 未作答

nn 个节点的单向链表中查找一个值,最坏需要访问( )个节点。

(1 分)
第 9 题 B3 未作答

判断题:头插法把新节点插入到链表头部,插入后新节点成为新的头节点。

(1 分)
第 10 题 B4 未作答

判断题:普通单链表尾插法需要先遍历到最后一个节点,再在其后接上新节点。

(1 分)
第 11 题 B5 未作答

在已知前驱节点 p 的情况下,向单链表插入新节点 q,需要修改( )个指针。

(1 分)
第 12 题 B6 未作答

判断题:删除单链表的节点,关键是把它前驱next 指向被删节点的后继。

(1 分)
第 13 题 B7 未作答

在单向链表中访问第 kk 个节点,需要( )。

(1 分)

复杂度对比

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

判断题:数组按下标随机访问是 O(1)O(1),链表按位置访问是 O(n)O(n)

(1 分)
第 15 题 C2 未作答

判断题:在已知位置指针的情况下,链表插入/删除节点的时间复杂度是 O(1)O(1)

(1 分)
第 16 题 C3 未作答

在数组中间插入一个元素,最坏需要移动( )个元素。

(1 分)
第 17 题 C4 未作答

判断题:在无序链表中查找一个元素的时间复杂度是 O(n)O(n)

(1 分)
第 18 题 C5 未作答

判断题:单链表头插/头删是 O(1)O(1),尾插/尾删是 O(n)O(n)(需遍历到尾部)。

(1 分)
第 19 题 C6 未作答

nn 个元素的中部反复插入删除,链表比数组( )(已知插入位置)。

(1 分)
第 20 题 C7 未作答

判断题:数组占用连续内存,链表节点分散在内存各处。

(1 分)

双向链表

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

判断题:双向链表的节点包含两个指针域,分别指向前驱和后继。

(1 分)
第 22 题 D2 未作答

在双向链表的已知节点 p 之后插入新节点,需要修改( )个指针。

(1 分)
第 23 题 D3 未作答

判断题:删除双向链表中的节点,只需把它的前驱和后继的指针接起来(修改 2 个指针),无需找前驱。

(1 分)
第 24 题 D4 未作答

判断题:双向链表可以沿 prev 指针从尾到头逆序遍历。

(1 分)
第 25 题 D5 未作答

判断题:双向链表找某个节点的前驱是 O(1)O(1),而单向链表需要从头遍历。

(1 分)
第 26 题 D6 未作答

判断题:双向链表比单向链表多一个指针域,空间开销更大。

(1 分)
第 27 题 D7 未作答

判断题:哨兵(哑)节点是链表头部的一个空节点,可以简化头插和删除的边界处理。

(1 分)

循环链表

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

判断题:循环链表中,最后一个节点的 next 指向头节点(或第一个节点)。

(1 分)
第 29 题 E2 未作答

判断题:遍历循环链表不能以 next == nullptr 为终止条件,否则会死循环。

(1 分)
第 30 题 E3 未作答

判断题:约瑟夫问题(报数出列)适合用循环链表模拟。

(1 分)
第 31 题 E4 未作答

判断题:带尾指针的循环链表,尾插(在尾部插入)是 O(1)O(1)

(1 分)
第 32 题 E5 未作答

判断题:用快慢指针(一个每次走 2 步、一个走 1 步)可以判断链表是否有环。

(1 分)
第 33 题 E6 未作答

判断题:从循环链表的任意节点出发,都能遍历到全部节点。

(1 分)

链表应用

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

判断题:用链表实现栈,头插头删即可使入栈出栈均为 O(1)O(1)

(1 分)
第 35 题 F2 未作答

判断题:用单链表实现队列,需要头删 + 尾插,尾插要 O(n)O(n)(除非维护尾指针)。

(1 分)
第 36 题 F3 未作答

判断题:哈希表的链地址法用链表把冲突的元素串在一起。

(1 分)
第 37 题 F4 未作答

判断题:LRU 缓存常用"哈希表 + 双向链表"实现,链表维护访问顺序。

(1 分)
第 38 题 F5 未作答

判断题:归并排序适合链表(无需随机访问,只需合并有序链),时间复杂度 O(nlogn)O(n \log n)

(1 分)
第 39 题 F6 未作答

判断题:反转单链表需要逐个改变节点的 next 方向,时间复杂度 O(n)O(n)

(1 分)

指针操作细节

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

判断题:在链表头部加哑节点后,头插和删除操作可以少写很多边界判断。

(1 分)
第 41 题 G2 未作答

判断题:单链表插入时,应先把新节点指向后继,再让前驱指向新节点(先连新、后断旧)。

(1 分)
第 42 题 G3 未作答

判断题:用 new 创建的链表节点,不再使用时应 delete 释放,防止内存泄漏。

(1 分)
第 43 题 G4 未作答

判断题:删除节点并 delete 后,若该指针仍被使用(未置空),会产生悬垂指针(未定义行为)。

(1 分)
第 44 题 G5 未作答

判断题:快慢指针可以 O(n)O(n) 找到链表中间节点(快指针到末尾时,慢指针在中点)。

(1 分)
第 45 题 G6 未作答

判断题:用两个指针(一前一后)遍历链表,可以方便地找到倒数第 kk 个节点等位置。

(1 分)

易错综合

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

下列场景中,更适合用链表的是( )。

(1 分)
第 47 题 H2 未作答

依次用头插法插入 1,2,31, 2, 3,最终链表从头到尾是( )。

(1 分)
第 48 题 H3 未作答

判断题:遍历循环链表若用 while (p != nullptr) 作终止条件,会死循环。

(1 分)
第 49 题 H4 未作答

单链表在 p 后插入 q,正确的操作顺序是( )。

(1 分)
第 50 题 H5 未作答

下列说法错误的是( )。

(1 分)

数组模拟链表

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

判断题:用数组模拟链表(静态链表)时,用 nxt[i] 存节点 ii 的下一个节点下标,用 -1 表示"没有后继"。

(1 分)
第 52 题 I2 未作答

判断题:静态链表中,head 存放的是第一个节点的下标,而不是节点本身。

(1 分)
第 53 题 I3 未作答

01int val[5] = {10, 20, 30, 40, 50};
02int nxt[5] = {1, 2, 3, 4, -1};
03int head = 0;
04for (int i = head; i != -1; i = nxt[i]) cout << val[i] << ' ';

以上代码输出( )。

(1 分)
第 54 题 I4 未作答

判断题:静态链表删除节点只需修改 nxt 指针跳过它;被删的下标可以回收进"空闲链表"复用。

(1 分)
第 55 题 I5 未作答

判断题:静态链表删除节点只需修改 nxt 指针跳过它;被删的下标可以回收进"空闲链表"复用。

(1 分)
第 56 题 I6 未作答

判断题:静态链表的长度受数组大小限制,不能像指针链表那样随意动态增长。

(1 分)

静态链表操作

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

01int val[10], nxt[10], head = -1, cnt = 0;
02for (int i = 1; i <= 3; i++) {
03    val[cnt] = i;
04    nxt[cnt] = head;
05    head = cnt;
06    cnt++;
07}
08for (int i = head; i != -1; i = nxt[i]) cout << val[i] << ' ';

以上代码输出( )。

(1 分)
第 58 题 J2 未作答

01int val[10], nxt[10], head = -1, tail = -1, cnt = 0;
02for (int i = 1; i <= 3; i++) {
03    val[cnt] = i; nxt[cnt] = -1;
04    if (head == -1) head = cnt; else nxt[tail] = cnt;
05    tail = cnt; cnt++;
06}
07for (int i = head; i != -1; i = nxt[i]) cout << val[i] << ' ';

以上代码输出( )。

(1 分)
第 59 题 J3 未作答

01int val[5] = {1, 2, 3, 4};
02int nxt[5] = {1, 2, 3, -1};
03int head = 0;
04for (int p = head; p != -1; p = nxt[p])
05    if (nxt[p] != -1 && val[nxt[p]] == 2) nxt[p] = nxt[nxt[p]];
06for (int i = head; i != -1; i = nxt[i]) cout << val[i] << ' ';

以上代码输出( )。

(1 分)
第 60 题 J4 未作答

01int val[4] = {1, 2, 3};
02int nxt[4] = {1, 2, -1};
03int head = 0, pre = -1, cur = head;
04while (cur != -1) {
05    int t = nxt[cur];
06    nxt[cur] = pre;
07    pre = cur; cur = t;
08}
09head = pre;
10for (int i = head; i != -1; i = nxt[i]) cout << val[i] << ' ';

以上代码输出( )。

(1 分)
第 61 题 J5 未作答

01int val[4] = {1, 2, 3, 4};
02int nxt[4] = {1, 2, 3, -1};
03int s = 0;
04for (int i = 0; i != -1; i = nxt[i]) s += val[i];
05cout << s;

以上代码输出( )。

(1 分)
第 62 题 J6 未作答

01int val[5] = {7, 3, 9, 5};
02int nxt[5] = {1, 2, 3, -1};
03int cnt = 0;
04for (int i = 0; i != -1; i = nxt[i]) cnt++;
05cout << cnt;

以上代码输出( )。

(1 分)
第 63 题 J7 未作答

01int val[5] = {3, 1, 4, 2};
02int nxt[5] = {1, 2, 3, -1};
03int mx = val[0];
04for (int i = nxt[0]; i != -1; i = nxt[i])
05    if (val[i] > mx) mx = val[i];
06cout << mx;

以上代码输出( )。

(1 分)
拾壹

代码阅读 · 遍历统计

7 QUESTIONS · 2 POINTS EACH
第 64 题 K1 未作答

01int val[5] = {3, 1, 4, 2, 7};
02int nxt[5] = {1, 2, 3, 4, -1};
03int cnt = 0;
04for (int i = 0; i != -1; i = nxt[i])
05    if (val[i] % 2 == 1) cnt++;
06cout << cnt;

以上代码输出( )。

(1 分)
第 65 题 K2 未作答

01int val[5] = {10, 20, 30, 40, 50};
02int nxt[5] = {1, 2, 3, 4, -1};
03int k = 3, cur = 0;
04for (int i = 1; i < k; i++) cur = nxt[cur];
05cout << val[cur];

以上代码输出( )。

(1 分)
第 66 题 K3 未作答

01int val[6] = {1, 2, 3, 4, 5};
02int nxt[6] = {1, 2, 3, 4, -1};
03int k = 2, p = 0, q = 0;
04for (int i = 0; i < k; i++) q = nxt[q];
05while (q != -1) { p = nxt[p]; q = nxt[q]; }
06cout << val[p];

以上代码输出( )。

(1 分)
第 67 题 K4 未作答

01int val[5] = {1, 3, 5, 7};
02int nxt[5] = {1, 2, 3, -1};
03bool ok = true;
04for (int i = 0; nxt[i] != -1; i = nxt[i])
05    if (val[i] >= val[nxt[i]]) ok = false;
06cout << (ok ? "YES" : "NO");

以上代码输出( )。

(1 分)
第 68 题 K5 未作答

01int val[6] = {5, 2, 8, 3, 9};
02int nxt[6] = {1, 2, 3, 4, -1};
03int x = 4, cnt = 0;
04for (int i = 0; i != -1; i = nxt[i])
05    if (val[i] > x) cnt++;
06cout << cnt;

以上代码输出( )。

(1 分)
第 69 题 K6 未作答

01int val[5] = {2, 4, 6, 8};
02int nxt[5] = {1, 2, 3, -1};
03int s = 0, n = 0;
04for (int i = 0; i != -1; i = nxt[i]) { s += val[i]; n++; }
05cout << s / n;

以上代码输出( )。

(1 分)
第 70 题 K7 未作答

01int val[6] = {7, 2, 9, 4};
02int nxt[6] = {1, 2, 3, -1};
03int mx = val[0], mn = val[0];
04for (int i = nxt[0]; i != -1; i = nxt[i]) {
05    if (val[i] > mx) mx = val[i];
06    if (val[i] < mn) mn = val[i];
07}
08cout << mx - mn;

以上代码输出( )。

(1 分)
拾贰

代码阅读 · 插入删除反转

7 QUESTIONS · 2 POINTS EACH
第 71 题 L1 未作答

01struct Node { int val; Node *next; };
02// 链表 1 → 2 → 3 → 4
03Node *pre = NULL, *cur = head;
04while (cur != NULL) {
05    Node *t = cur->next;
06    cur->next = pre;
07    pre = cur; cur = t;
08}
09head = pre;
10// 依次输出 val

反转后从头输出为( )。

(1 分)
第 72 题 L2 未作答

// 链表 1 → 2 → 3 → 4 → 5
// 执行删除所有偶数节点的操作后,从头输出为( )。

(1 分)
第 73 题 L3 未作答

01struct Node { int val; Node *next; };   // 链表节点定义
02Node *head = NULL;
03for (int i = 5; i >= 1; i--) {
04    Node *p = new Node;
05    p->val = i;
06    p->next = head;
07    head = p;
08}
09// 依次输出 val

以上代码输出( )。

(1 分)
第 74 题 L4 未作答

// 链表 1 → 2 → 3 → 4 → 5,删除倒数第 2 个节点后,从头输出为( )。

(1 分)
第 75 题 L5 未作答

// 链表 1 → 2 → 3 → 4,执行"相邻两两交换"(1 与 2 换、3 与 4 换)后,从头输出为( )。

(1 分)
第 76 题 L6 未作答

// 有序链表 1 → 3 → 5,插入节点 4(保持有序)后,从头输出为( )。

(1 分)
第 77 题 L7 未作答

// 有序链表 1 → 2 → 2 → 3 → 3,删除重复节点(每个值只保留一个)后,从头输出为( )。

(1 分)
拾叁

代码阅读 · 双向循环

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

01struct Node { int val; Node *prev, *next; };
02// 双向链表 1 ↔ 2 ↔ 3,head 指向 1
03for (Node *p = head; p != NULL; p = p->next) cout << p->val << ' ';

以上代码输出( )。

(1 分)
第 79 题 M2 未作答

01struct Node { int val; Node *prev, *next; };   // 双向链表节点
02// 构建双向链表 1 ↔ 2 ↔ 3,tail 指向 3
03Node *n1 = new Node{1, NULL, NULL};
04Node *n2 = new Node{2, NULL, NULL};
05Node *n3 = new Node{3, NULL, NULL};
06n1->next = n2; n2->prev = n1;
07n2->next = n3; n3->prev = n2;
08Node *tail = n3;
09for (Node *p = tail; p != NULL; p = p->prev) cout << p->val << ' ';

以上代码输出( )。

(1 分)
第 80 题 M3 未作答

01struct Node { int val; Node *next; };   // 链表节点定义
02// 构建循环链表 1 → 2 → 3 →(回到 1),head 指向 1
03Node *n1 = new Node{1, NULL};
04Node *n2 = new Node{2, NULL};
05Node *n3 = new Node{3, NULL};
06n1->next = n2; n2->next = n3; n3->next = n1;
07Node *head = n1;
08Node *p = head;
09for (int i = 1; i <= 7; i++) { cout << p->val << ' '; p = p->next; }

以上代码输出( )。

(1 分)
第 81 题 M4 未作答

// n = 5 个人围成一圈(编号 1~5),从 1 开始报数,报到 2 的人出列,
// 出列后从下一个人重新报数。用循环链表模拟,出列顺序是( )。

(1 分)
第 82 题 M5 未作答

// 循环链表 1 → 2 →(回到 1),tail 指向 2。
// 执行:在 tail 后插入节点 3,然后从 tail->next 开始输出 3 个节点,输出为( )。

(1 分)
第 83 题 M6 未作答

01// 判断链表是否有环的经典代码:
02bool hasCycle(Node *head) {
03    Node *slow = head, *fast = head;
04    while (fast != NULL && fast->next != NULL) {
05        slow = slow->next;
06        fast = fast->next->next;
07        if (slow == fast) return true;
08    }
09    return false;
10}

判断题:若链表无环,fast 会先到达 NULL,循环正常结束并返回 false

(1 分)
拾肆

完善程序 · 链表功能

7 QUESTIONS · 2 POINTS EACH
第 84 题 N1 未作答

// 静态链表头插:在 head 前插入新节点 q
nxt[q] = ______;
head = q;

横线处应填( )。

(1 分)
第 85 题 N2 未作答

// 静态链表尾插(维护 tail 指针)
nxt[tail] = q;
nxt[q] = -1;
tail = ______;

横线处应填( )。

(1 分)
第 86 题 N3 未作答

// 删除节点 q(p 是 q 的前驱)
nxt[p] = ______;

横线处应填( )。

(1 分)
第 87 题 N4 未作答

01// 反转静态链表(pre 已指向当前节点的前一个)
02while (cur != -1) {
03    int t = nxt[cur];
04    nxt[cur] = pre;
05    pre = cur;
06    cur = ______;
07}

横线处应填( )。

(1 分)
第 88 题 N5 未作答

01// 在静态链表中查找值为 x 的节点,返回其下标;找不到返回 -1
02int find(int head, int x) {
03    for (int i = head; i != -1; i = nxt[i])
04        if (val[i] == x) return i;
05    return ______;
06}

横线处应填( )。

(1 分)
第 89 题 N6 未作答

01// 统计链表节点个数
02int countNodes(int head) {
03    int cnt = 0;
04    for (int i = head; i != -1; i = nxt[i])
05        ______;
06    return cnt;
07}

横线处应填( )。

(1 分)
第 90 题 N7 未作答

01// 读入 n 个数(1~n 依次),静态链表尾插建链(head 为头、tail 为尾)
02for (int i = 0; i < n; i++) {
03    val[cnt] = i + 1;
04    nxt[cnt] = -1;
05    if (head == -1) head = cnt;
06    else ______;
07    tail = cnt;
08    cnt++;
09}

横线处应填( )。

(1 分)
拾伍

代码综合 · 链表应用

5 QUESTIONS · 2 POINTS EACH
第 91 题 O1 未作答

// 用链表实现栈:push 1、push 2、push 3,然后依次 pop 并输出,输出为( )。

(1 分)
第 92 题 O2 未作答

// 用链表实现队列(维护头尾指针):入队 1、2、3,然后依次出队并输出,输出为( )。

(1 分)
第 93 题 O3 未作答

// n = 5,k = 2(报数到 2 出列),用循环链表模拟:
// 出列顺序依次为 2, 4, 1, 5,最后剩下的是( )。

(1 分)
第 94 题 O4 未作答

判断题:邻接表用"数组头结点 + 链表"存储图的边,本质是静态链表(每个顶点的边用链表串起来)。

(1 分)
第 95 题 O5 未作答

判断题:用链表实现栈时,把栈顶放在链表头部(头插头删),入栈出栈都是 O(1)O(1)

(1 分)
拾陆

代码易错

5 QUESTIONS · 2 POINTS EACH
第 96 题 P1 未作答

// 链表 1 → 2 → 3 → 4,p 指向值为 2 的节点,q 是新节点
// 在 p 后插入 q,执行下面这段代码:
p->next = q;
q->next = p->next;

判断题:执行后 q->next 指向 q 自己,原链表 p 之后的节点全部丢失。

(1 分)
第 97 题 P2 未作答

// 链表 1 → 2 → 3,头指针 head 指向 1
// 头插一个新节点 q(值为 0),但忘记更新 head:
q->next = head;
// head 仍然是旧头

判断题:不更新 head 的话,新节点 q 永远不会被访问到。

(1 分)
第 98 题 P3 未作答

01// 静态链表:val[5] = {1, 2, 3, 4, 5},nxt 链 0→1→2→3→-1,head = 0
02// 遍历时把循环条件写错:
03for (int i = head; nxt[i] != -1; i = nxt[i]) cout << val[i] << ' ';

判断题:循环条件的错误导致最后一个节点不会被输出。

(1 分)
第 99 题 P4 未作答

// q 指向链表中某个 new 出来的节点
// 删除节点 q 后:
delete q;
// 之后又执行 cout << q->val;

判断题:delete q 后再使用 q 是未定义行为(悬垂指针)。

(1 分)
第 100 题 P5 未作答

// 静态链表:val[0..2] = {1, 2, 3},nxt = {1, 2, -1},head = 0
// 执行:nxt[1] = nxt[2];  (即删除下标 2 的节点 3)

判断题:执行后从头遍历输出为 1 2,节点 3 被"跳过"。

(1 分)