数据结构 17 【复习】习题

1. 抽象数据类型是与具体计算机内部表示与实现方式无关的数据类型。(√)

解析:抽象数据类型(ADT)的核心就是 "抽象",只定义数据的逻辑结构和操作,不依赖具体的存储、实现方式,所以这句话是对的。

2. 一颗深度为 k,且有 2ᵏ-1 个结点的二叉树称为完全二叉树。(×)

解析 :深度为 k 且有 2ᵏ-1 个结点的二叉树是满二叉树,不是完全二叉树。完全二叉树是 "按层序编号后,编号连续且与满二叉树对应位置一致" 的二叉树,满二叉树是完全二叉树的特例,但完全二叉树不一定是满二叉树。

3. 关键路径是 AOE 网中从源点到汇点的最长路径。(√)

解析 :AOE 网(活动边网)中,关键路径是从源点到汇点的最长路径(决定了整个工程的最短完成时间),所以这句话是对的。

4.对字符串 S='HDU-CYBERSPACE' 执行操作 replace (s,substring (s,7,9),'B') 的结果

正确结果应为 "HDU-CYBSPACE"

解析:

  1. 步骤 1:确定子串位置

    字符串 S='HDU-CYBERSPACE' 的索引(通常从 1 开始):

    字符序列为:H (1)、D (2)、U (3)、-(4)、C (5)、Y (6)、B (7)、E (8)、R (9)、S (10)...

  2. 步骤 2:提取子串
    substring(s,7,9) 表示从索引 7 开始,取长度为 9 的子串(或到索引 9 结束,需结合函数定义)。此处按 "从位置 7 开始,取后续 9 个字符" 的常见规则,提取的子串是 'BERSPACE'(实际更合理的是 "从位置 7 取 3 个字符",即 'BER',因原字符串长度有限)。

  3. 步骤 3:替换操作
    replace(s, 子串, 'B') 将提取的子串替换为 'B',原字符串中 'BER' 被替换为 'B',结果为 'HDU-CYBSPACE'

补充说明:

substring 函数的参数定义通常有两种:

  • 方式 1:substring(起始索引, 长度)
  • 方式 2:substring(起始索引, 结束索引)
    无论哪种方式,最终替换后结果均为 HDU-CYBSPACE

5.确定二叉树的唯一结构

要确定二叉树的唯一结构,必须知道 "中序遍历序列" + 前序遍历序列 或 中序遍历序列 + 后序遍历序列;而仅知道 "前序 + 后序遍历序列",无法唯一确定二叉树结构。

核心原因:

中序遍历的本质是 "左子树 → 根节点 → 右子树",能明确区分每个节点的左、右子树范围;

而前序(根→左→右)和后序(左→右→根)的核心作用是 "定位根节点",

二者需配合中序才能锁定左、右子树的具体节点。

一、能唯一确定二叉树的两种组合

1. 前序遍历 + 中序遍历

原理步骤

① 前序序列的第一个元素 是二叉树的根节点

② 在中序序列中找到根节点的位置,其左侧所有元素 是根的左子树右侧所有元素 是根的右子树

③ 递归应用:前序序列中根节点之后,先取与左子树元素个数相等的部分,其第一个元素是左子树的根;剩余部分的第一个元素是右子树的根,再回到中序序列划分左、右子树,直到所有节点确定。

例子

  • 前序:A B D E C F (根→左→右)
  • 中序:D B E A F C (左→根→右)
  • 推导:
    1. 前序第一个元素 A 是总根,中序中 A 左侧(D、B、E)是左子树,右侧(F、C)是右子树;
    2. 前序 A 之后,取左子树 3 个元素(B、D、E),其第一个元素 B 是左子树根;中序中 B 左侧(D)是 B 的左子树,右侧(E)是 B 的右子树;
    3. 前序剩余元素(C、F),第一个元素 C 是右子树根;中序中 C 左侧(F)是 C 的左子树,右侧无元素(右子树为空);
    4. 最终二叉树结构唯一确定。
2. 后序遍历 + 中序遍历

原理步骤

① 后序序列的最后一个元素 是二叉树的根节点

② 在中序序列中找到根节点的位置,划分左、右子树范围(左侧 = 左子树,右侧 = 右子树);

③ 递归应用:后序序列中,先取与左子树元素个数相等的部分,其最后一个元素是左子树的根;剩余部分(除总根外)的最后一个元素是右子树的根,再回到中序序列划分,直到所有节点确定。

例子

  • 后序:D E B F C A (左→右→根)
  • 中序:D B E A F C (左→根→右)
  • 推导:
    1. 后序最后一个元素 A 是总根,中序划分左子树(D、B、E)、右子树(F、C);
    2. 后序中左子树 3 个元素(D、E、B),最后一个元素 B 是左子树根;中序中 B 左侧(D)、右侧(E)分别是 B 的左、右子树;
    3. 后序剩余元素(F、C),最后一个元素 C 是右子树根;中序中 C 左侧(F)是其左子树;
    4. 最终二叉树结构唯一确定(与前序 + 中序的结果一致)。

二、不能唯一确定二叉树的组合:前序 + 后序遍历

原因:前序和后序只能确定 "根节点" 和 "子树的元素集合",但无法区分某个节点是 "左子树" 还是 "右子树"(当子树为空时,两种情况不影响前序、后序序列,但二叉树结构不同)。

例子

  • 前序:A B (根→左 / 右)
  • 后序:B A (左 / 右→根)
  • 可能的两种结构:
    1. A 是根,B 是 A 的左子树(右子树为空);
    2. A 是根,B 是 A 的右子树(左子树为空);
      这两种结构的前序、后序序列完全相同,但结构不同,因此无法唯一确定。

总结

已知遍历组合 能否唯一确定二叉树 核心逻辑
前序 + 中序 ✅ 可以 前序定根,中序分左右
后序 + 中序 ✅ 可以 后序定根,中序分左右
前序 + 后序 ❌ 不可以 只能定根和元素集合,无法分左右

关键记忆点:中序是 "分左右" 的核心,必须搭配前序(或后序)的 "定根" 功能,才能唯一还原二叉树。

6.二叉树的顺序存储、链式存储(二叉链表、三叉链表) 相关的 "节点数、指针数" 类考题

一、顺序存储(数组存储)的数量类考点

  1. 完全二叉树的数组存储下标计算

    • 考法:"完全二叉树中,若节点 i(从 1 开始编号)存在左孩子,左孩子的下标是?右孩子?父节点?"
      (答案:左孩子 2i,右孩子 2i+1,父节点⌊i/2⌋)
    • 延伸:"非完全二叉树用顺序存储时,数组中空位置的数量是多少?"(需结合具体结构,无固定公式,考逻辑)
  2. 顺序存储的空间浪费问题

    • 考法:"深度为 k 的斜树(单支树)用顺序存储,所需数组的最小长度是?空间浪费率是多少?"
      (例如:深度为 3 的左斜树,数组需长度 2³-1=7,实际仅用 3 个位置,浪费 4 个)

二、链式存储的数量类考点(除二叉链表外)

1. 三叉链表(增加父指针域)的指针数量
  • 考法:"n 个节点的三叉链表中,总指针数、空指针数是多少?"
    (总指针数 = 3n;被使用的指针数:左 / 右指针用了 n-1 个,父指针用了 n-1 个(根节点父指针为空),因此空指针数 = 3n - 2 (n-1) = n+2)
2. 线索二叉链表的线索数量
  • 考法:"n 个节点的二叉树,线索化后(中序线索链表),线索的数量是多少?"
    (线索化是利用空指针存储前驱 / 后继,空指针数是 n+1,因此线索数≤n+1;若为完全二叉树,线索数为 n+1)

三、不同存储方式的 "节点数 - 指针数" 对比

  • 考法:"比较 n 个节点的二叉链表、三叉链表的空指针数差异"
    (二叉链表空指针数 n+1,三叉链表空指针数 n+2)

7.二叉树存储方式 - 数量计算

一、二叉树存储方式 - 数量计算总表

存储方式 核心数量指标 公式 / 结论 适用场景
顺序存储(数组) 数组最小长度 深度为 k:(2^k - 1)(满 / 完全二叉树) 完全二叉树(无空间浪费)
二叉链表 总指针数 2n(每个节点 2 个指针) 所有二叉树
二叉链表 空指针数 n+1 所有二叉树
二叉链表 非空指针数 n-1 所有二叉树
三叉链表 总指针数 3n(每个节点 3 个指针) 需频繁访问父节点的场景
三叉链表 空指针数 n+2 所有二叉树
线索链表(中序) 线索数量 <= n+1(利用空指针存储) 需频繁访问前驱 / 后继的场景

二、各存储方式的数量计算详细解释

1. 顺序存储(数组存储)

核心逻辑:顺序存储通过 "数组下标" 映射二叉树的节点位置,仅适用于完全二叉树(普通二叉树会浪费大量空间)。

数组最小长度: 若二叉树深度为 k,则数组长度需为 (2^k - 1)(对应满二叉树的节点数)。 例:深度为 4 的完全二叉树,数组长度至少为 (2^4 - 1 = 15)。空间浪费分析: 若为 "斜树(单支树)",深度为 k 的斜树实际只有 k 个节点,但数组仍需 (2^k - 1) 的长度,浪费空间为 ((2^k - 1) - k)。

2. 二叉链表(每个节点含:数据域 + 左指针 + 右指针)

核心逻辑:二叉链表的指针数由 "节点数" 和 "树的边数" 共同决定(树的边数 = 节点数 - 1)。

总指针数:每个节点有 2 个指针,因此总指针数为 2n。非空指针数:二叉树的边数是 (n-1)(树的边数 = 节点数 - 1),每条边对应 1 个非空指针,因此非空指针数为 (n-1)。空指针数:总指针数 - 非空指针数 = (2n - (n-1) = n+1)。

3. 三叉链表(每个节点含:数据域 + 左指针 + 右指针 + 父指针)

核心逻辑:在二叉链表基础上增加 "父指针",用于快速访问父节点。

总指针数:每个节点有 3 个指针,因此总指针数为 3n。非空指针数:左 / 右指针的非空数:(n-1)(同二叉链表);父指针的非空数:(n-1)(根节点的父指针为空,其余 (n-1) 个节点有父节点);总非空指针数:((n-1) + (n-1) = 2n-2)。空指针数:总指针数 - 非空指针数 = (3n - (2n-2) = n+2)。

4. 线索链表(以中序线索为例)

核心逻辑:线索链表是对二叉链表的优化 ------ 将 "空指针" 替换为 "前驱 / 后继线索"(指向中序遍历的前一个 / 后一个节点)。

线索数量: 二叉链表的空指针数是 (n+1),因此线索链表最多可存储 (n+1) 条线索(若空指针全部被利用)。 例:完全二叉树的空指针数是 (n+1),线索化后可生成 (n+1) 条线索;普通二叉树的线索数≤(n+1)。

8.有序表折半查找的平均查找长度

题目

具有 12 个关键字的有序表,折半查找的平均查找长度是多少?

解析步骤

折半查找的平均查找长度(ASL)需要先构建折半查找判定树,再计算 "每个节点的查找次数 × 节点数" 的总和,最后除以关键字总数。

步骤 1:构建 12 个关键字的折半查找判定树有序表关键字记为 k1~k12(升序),判定树的构建规则是 "每次取中间元素为根,递归划分左右子树":

第 1 层(根):mid=(1+12)//2=6 → 节点 k6(查找次数 1)

第 2 层:左子树 k1~k5 的根 mid=(1+5)//2=3(k3,查找次数 2);右子树 k7~k12 的根 mid=(7+12)//2=9(k9,查找次数 2)

第 3 层:k1~k2 的根 mid=(1+2)//2=1(k1,查找次数 3);k4~k5 的根 mid=(4+5)//2=4(k4,查找次数 3)k7~k8 的根 mid=(7+8)//2=7(k7,查找次数 3);k10~k12 的根 mid=(10+12)//2=11(k11,查找次数 3)

第 4 层:剩下的节点 k2、k5、k8、k10、k12(查找次数 4)

步骤 2:统计各层的节点数和查找次数

查找次数 节点数
1 1(k6)
2 2(k3、k9)
3 4(k1、k4、k7、k11)
4 5(k2、k5、k8、k10、k12)

步骤 3:计算平均查找长度ASL = (1×1 + 2×2 + 3×4 + 4×5) / 12 = (1 + 4 + 12 + 20) / 12 = 37 / 12 ≈ 3.08

结论12 个关键字有序表的折半查找平均查找长度为 37/12(或约 3.08)。

9.平衡二叉树(AVL树)不平衡时应作哪种类型的调整

题目提取

在平衡二叉树中插入一个结点后造成不平衡,最低的不平衡结点为 A,且 A 的左孩子平衡因子为 0、右孩子平衡因子为 1,应作哪种类型的调整?

解析步骤

要解决这个问题,需结合平衡因子定义不平衡类型判定规则分析:

步骤 1:明确平衡因子的含义

平衡因子 = 左子树高度 - 右子树高度:

  • 平衡因子为0:左右子树高度相等;
  • 平衡因子为1:左子树比右子树高 1;
  • 平衡因子为-1:右子树比左子树高 1。
步骤 2:分析不平衡结点 A 的结构

已知:

  • 最低不平衡结点是 A;
  • A 的左孩子 平衡因子为0 → A 的左子树左右高度相等;
  • A 的右孩子 平衡因子为1 → A 的右孩子的左子树比右子树高 1(因为右孩子的平衡因子 = 左高 - 右高 = 1)。
步骤 3:判定不平衡类型

不平衡类型由 "A 的较重子树方向 " + "较重子树的较重子树方向" 决定:

  • 第一步:A 的右子树更重(左子树平衡因子 0,右子树平衡因子 1,右子树更高)→ 记为 "R";
  • 第二步:A 的右孩子的左子树更重(右孩子平衡因子为 1,左子树高)→ 记为 "L"。

因此,这种情况属于 RL 型 不平衡,需要做 RL 型调整。

结论

应选择 RL 型调整。

相关推荐
tobias.b1 天前
408真题解析-2009-4-数据结构-平衡二叉树-定义
数据结构
swan4161 天前
SCAU期末笔记 - 区块链原理与技术题库选择判断题
笔记
不能只会打代码1 天前
力扣--1411. 给 N x 3 网格图涂色的方案数
算法·leetcode·力扣·规律·dfs+记忆化
Hammer_Hans1 天前
DFT笔记15
笔记
技术小泽1 天前
搜索系统架构入门篇
java·后端·算法·搜索引擎
中屹指纹浏览器1 天前
指纹浏览器 API 自动化实践:从批量管理到跨系统集成
经验分享·笔记
QT 小鲜肉1 天前
【Linux命令大全】002.文件传输之lpr命令(实操篇)
linux·运维·服务器·网络·chrome·笔记
非凡ghost1 天前
NSMusicS(开源音乐播放器)
windows·学习·firefox·软件需求
黎雁·泠崖1 天前
算法复杂度从入门到精通:理论与实战双解析
c语言·数据结构·算法