数据结构算法应用题
408(全国硕士研究生招生考试计算机学科专业基础)历年数据结构算法大题,枚举如下:
2009:链表中倒数第 k 个节点
题目
面试题 02.02. 返回倒数第 k 个节点 - 力扣(LeetCode)
已知一个带有头结点的单链表,结点结构为:
假设该链表只给出了头指针 list。在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第 k 个位置上的结点(k 为正整数)。若查找成功,算法输出该结点的 data 域的值,并返回 1;否则,只返回 0。要求:
- 描述算法的基本设计思想;
- 描述算法的详细实现步骤;
- 根据设计思想和实现步骤,采用程序设计语言描述算法(使用 C、C++ 或 Java 语言实现),关键之处请给出简要注释。
难度:简单
考察单链表、同向双指针
2010:189. 旋转数组
题目
189. 轮转数组 - 力扣(LeetCode)
设计将 n(n > 1)个整数存放到一维数组 R 中。试设计一个在时间和空间两方面都尽可能高效的算法,将 R 中保存的序列循环左移 p(0 < p < n)个位置。即将 R 中的数据由()变换为()。要求:
- 给出算法的基本设计思想;
- 根据设计思想,采用 C 或 C++ 或 JAVA 语言描述算法,关键之处给出注释;
- 说明你所设计算法的时间复杂度和空间复杂度。
难度:中等
考察数组的原地翻转
2011:4. 寻找两个正序数组的中位数
题目
4. 寻找两个正序数组的中位数 - 力扣(LeetCode)
一个长度为 ()的升序序列 ,处在第 个位置的数称为 的中位数。
例如,若序列 ,则 的中位数是 ;两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若 ,则 和 的中位数是 。现在有两个等长升序序列 和 ,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列 和 的中位数。要求:
- 给出算法的基本设计思想。
- 根据设计思想,采用 C 或 C++ 或 JAVA 语言描述算法,关键之处给出注释。
- 说明你所设计算法的时间复杂度和空间复杂度。
难度:困难
考察二分查找、分块
2012:160. 相交链表
题目
假定采用带头结点的单链表保存单词,当两个单词有相同的后缀时,则可共享相同的后缀存储空间,例如,“loading”和“being”的存储映像如下图所示。
设 str1 和 str2 分别指向两个单词所在单链表的头结点,链表结点结构为 ,请设计一个时间上尽可能高效的算法,找出由 str1 和 str2 所指向两个链表共同后缀的起始位置(如图中字符 i 所在结点的位置 p)。要求:
- 给出算法的基本设计思想。
- 根据设计思想,采用 C 或 C++ 或 JAVA 语言描述算法,关键之处给出注释。
- 说明你所设计算法的时间复杂度。
难度:简单
考察分叉链表及双指针
2013:169. 多数元素
题目
169. 多数元素 - 力扣(LeetCode)
设包含 4 个数据元素的集合 S={"do", "for", "repeat", "while"},各元素的查找概率依次为:, , , 。将 保存在一个长度为 4 的顺序表中,采用折半查找法,查找成功时的平均查找长度为 2.2。请回答:
- 若采用顺序存储结构保存 ,且要求平均查找长度更短,则元素应如何排列?应使用何种查找方法?查找成功时的平均查找长度是多少?
- 若采用链式存储结构保存 ,且要求平均查找长度更短,则元素应如何排列?应使用何种查找方法?查找成功时的平均查找长度是多少?
难度:简单
考察摩尔投票法。
2014:二叉树的带权路径长度
题目
1376. 通知所有员工所需的时间 - 力扣(LeetCode) 二叉树的带权路径长度 (WPL) 是二叉树中所有叶结点的带权路径长度之和。给定一棵二叉树 ,采用二叉链表存储,结点结构为:
其中叶结点的 weight 域保存该结点的非负权值。设 root 为指向 的根结点的指针,请设计求 的 WPL 的算法,要求:
- 给出算法的基本设计思想;
- 使用 C 或 C++ 语言,给出二叉树结点的数据类型定义;
- 根据设计思想,采用 C 或 C++ 语言描述算法,关键之处给出注释。
难度:中等
考察带权路径长度 WPL 的概念以及广度优先遍历 BFS 或深度优先遍历 DFS。
2015:83. 删除排序链表中的重复元素
题目
83. 删除排序链表中的重复元素 - 力扣(LeetCode) 用单链表保存 m 个整数,结点的结构为:,且 (n 为正整数)。现要求设计一个时间复杂度尽可能高效的算法,对于链表中 data 的绝对值相等的结点,仅保留第一次出现的结点而删除其余绝对值相等的结点。例如,若给定的单链表 head 如下:

则删除结点后的 head 为:

要求:
- 给出算法的基本设计思想。
- 使用 C 或 C++ 语言,给出单链表结点的数据类型定义。
- 根据设计思想,采用 C 或 C++ 语言描述算法,关键之处给出注释。
- 说明你所设计算法的时间复杂度和空间复杂度。
难度:简单
考察单链表遍历。
2016:698. 划分为 k 个相等的子集
题目
698. 划分为k个相等的子集 - 力扣(LeetCode) 已知由 () 个正整数构成的集合 ,将其划分为两个不相交的子集 和 ,元素个数分别是 和 , 和 中元素之和分别为 和 。设计一个尽可能高效的划分算法,满足 最小且 最大。要求:
- 给出算法的基本设计思想。
- 根据设计思想,采用 C 或 C++ 语言描述算法,关键之处给出注释。
- 说明你所设计算法的平均时间复杂度和空间复杂度。
难度:中等
考察排序,利用快速排序 Pivot 思想对数组进行分组。
2017:将二叉树转换中缀表达式
题目
反向题目:1597. 根据中缀表达式构造二叉表达式树 - 力扣(LeetCode) 请设计一个算法,将给定的表达式树(二叉树)转换为等价的中缀表达式(通过括号反映操作符的计算次序)并输出。例如,当下列两棵表达式树作为算法的输入时:

输出的等价中缀表达式分别为 和 。
二叉树结点定义如下:
typedef struct node{
char data[10]; //存储操作数或操作符
struct node *left, *right;
}BTree;要求:
- 给出算法的基本设计思想。
- 根据设计思想,采用 C 或 C++ 语言描述算法,关键之处给出注释。
难度:简单
考察二叉树中序遍历。
2018:41. 缺失的第一个正数
题目
41. 缺失的第一个正数 - 力扣(LeetCode) 给定一个含 个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数。例如,数组 中未出现的最小正整数是 ;数组 中未出现的最小正整数是 。要求:
- 给出算法的基本设计思想。
- 根据设计思想,采用 C 或 C++ 语言描述算法,关键之处给出注释。
- 说明你所设计算法的时间复杂度和空间复杂度。
难度:困难
考察数组的原地标记,技巧性极强。
2019:143. 重排链表
题目
143. 重排链表 - 力扣(LeetCode) 设线性表 采用带头结点的单链表保存,链表中的结点定义如下:
typedef struct node
{ int data;
struct node*next;
} NODE;请设计一个空间复杂度为 且时间上尽可能高效的算法,重新排列 中的各结点,得到线性表 。要求:
- 给出算法的基本设计思想。
- 根据设计思想,采用 C 或 C++ 语言描述算法,关键之处给出注释。
难度:中等
考察链表的原地翻转,交叉连接,快慢指针找中间结点。
2020:不同数组中元素间的最小距离
题目
定义三元组 ( 均为正数)的距离 。给定 3 个非空整数集合 、 和 ,按升序分别存储在 3 个数组中。请设计一个尽可能高效的算法,计算并输出所有可能的三元组 (其中 )中的最小距离。例如 ,,,则最小距离为 ,相应的三元组为 。
要求:
- 给出算法的基本设计思想。
- 根据设计思想,采用 C 或 C++ 语言描述算法,关键之处给出注释。
- 说明你所设计算法的时间复杂度和空间复杂度。
难度:未知(个人评价中等)
不同数组中元素间的最小距离,多指针法,技巧性极强。
2021:未找到对应原题
题目
已知无向连通图 G 由顶点集 V 和边集 E 组成,,当 G 中度为奇数的顶点个数为不大于 2 的偶数时,G 存在包含所有边且长度为 的路径(称为 EL 路径)。设图 G 采用邻接矩阵存储,类型定义如下:
typedef struct { // 图的定义
int numVertices, numEdges; // 图中实际的顶点数和边数
char VerticesList[MAXV]; // 顶点表,MAXV为已定义常量
int Edge[MAXV][MAXV]; // 邻接矩阵
}MGraph;请设计算法 int IsExistEL(MGraph G),判断 G 是否存在 EL 路径,若存在,则返回 1 ,否则返回 0。要求:
- 给出算法的基本设计思想。
- 根据设计思想,采用 C 或 C++ 语言描述算法,关键之处给出注释。
- 说明你所设计算法的时间复杂度和空间复杂度。
难度:简单
考察无向图顶点度的概念和邻接矩阵的遍历,虽然是简单题,但是意味着 408 开始把图论纳入考察范围。
2022:新增考点:并查集,红黑树
题目
已知非空二叉树 的结点值均为正数,采用顺序存储方式保存,数据结构定义如下:
typedef struct { // MAX_SIZE为已定义常量
Elemtype SqBiTNode[MAX_SIZE]; // 保存二叉树结点值的数组
int ElemNum; // 实际占用的数组元素个数
}SqBiTree; 中不存在的结点在数组 SqBiTNode 中用 表示。例如,对于下图所示的两棵非空二叉树 和 :

请设计一个尽可能高效的算法,判定一棵采用这种方式存储的二叉树是否为二叉搜索树,若是,则返回 true,否则,返回 false,要求:
- 给出算法的基本设计思想。
- 根据设计思想,采用 C 或 C++ 语言描述算法,关键之处给出注释。
个人认为考察红黑树代码的可能性不大,考察并查集代码确有可能,并查集模板虽然有点长,但的确是一个可以千变万化的动态算法。
2023:非空有向图的 K 顶点个数
题目
已知有向图 采用邻接矩阵存储,类型定义如下:
typedef struct { // 图的类型定义
int numVertices, numEdges; // 图中顶点数和有向边数
char VerticesList[MAXV]; // 顶点表,MAXV为已定义常量
int Edge[MAXV][MAXV]; // 邻接矩阵
} MGraph;将图中出度大于入度的顶点称为 K 顶点。例如在题 41 图中,顶点 和 都是 K 顶点。

请设计算法:
int printVertices(MGraph G),对给定的任意非空有向图 ,输出 中所有 K 顶点,并返回 K 顶点的个数。要求:
- 给出算法的基本设计思想。
- 根据设计思想,采用 C 或 C++ 语言描述算法,关键之处给出注释。
难度:中等
2024:判定拓扑序列的唯一性
题目
2023 年 10 月 26 日,神舟十七号载人飞船发射取得圆满成功,再次彰显了中国航天事业的辉煌成就。载人航天工程是包含众多子工程的复杂系统工程,为了保证工程的有序展开,需要明确各子工程的前导子工程,以协调各子工程的实施。该问题可以简化、抽象为有向图的拓扑序列问题。已知有向图 G 采用邻接矩阵存储,类型定义如下:
typedef struct { // 图的类型定义
int numVertices, numEdges; // 图的顶点数和有向边数
char VerticesList[MAXV]; // 顶点表,MAXV为已定义常量
int Edge[MAXV][MAXV]; // 邻接矩阵
} MGraph;请设计算法:int uniquely(MGraph G),判定 G 是否存在唯一的拓扑序列。若是,则返回 1,否则返回 0。
要求如下。
- 给出算法的基本设计思想。(4 分)
- 根据设计思想,采用 C 或 C++ 语言描述算法,关键之处给出注释。(9 分)
难度:中等
BFS/BPS
2025:数组元素最大乘积问题
题目
有两个长度均为 的一维整型数组 、,计算 与
()乘积的最大值,并将其保存到 中。若 ,则得到 。现给定数组 ,请设计时间空间上尽可能高效的算法 ,求 中各元素的值。函数原型为:void CalMulMax(int A[], int res[], int n)。
- 给出算法的基本思想。(4 分)
- 用 C/C++ 描述算法关键之处给出注释。(7 分)
- 说明时间、空间复杂度。(2 分)
难度:中等
一次遍历保存最大正数和最大负数,而后根据符号与最大值相乘。