
简介这份湖北大学数据结构期末试卷2022—2023学年度第一学期A卷面向计算机与信息工程学院信息安全等专业学生用于期末复习与知识点自测。试卷覆盖图论、查找算法、二叉树遍历、递归函数与存储结构等核心章节题型包含判断分析、简答与应用分析涉及带权有向图关键路径、邻接表存储、顺序查找平均查找长度、先序中序推后序、递归求幂调用次数、链栈适用性、二路归并排序、普里姆与克鲁斯卡尔算法、二叉排序树构造及哈希线性探查等内容兼顾理论分析与算法实现。资源为1个PDF文件压缩包约252KB完整呈现原卷试题纸与分值分布便于打印练习。目前已有375人学习下载适合需要系统梳理考点、检验复习效果的读者对照使用。1. 一份期末卷子拆开看数据结构到底考什么、怎么练很多人复习数据结构习惯把教材从头翻到尾结果图论看了一半又回去翻链表最后什么都没记住。我拿到这份试卷的第一反应不是“题难不难”而是“它把考点分布得很清楚”——判断题、简答题、应用分析题、程序设计题四类覆盖了图、树、查找、排序、递归、存储结构六个模块。换句话说它本身就是一份现成的复习路线图。如果你正在准备数据结构期末或者想用一套完整的题目检验自己的掌握程度这份卷子的价值不在于“押题”而在于它把每个知识点的考查方式都摆出来了概念辨析考判断原理理解考简答过程推导考应用代码能力考设计。下面我按题型拆开讲每类题怎么下手、参数怎么算、哪里容易翻车。2. 判断题与简答题概念辨析的五个高频翻车点2.1 关键路径缩短不等于工期缩短判断题第一题问的是缩短关键路径上某个活动的时间是否一定能缩短整个工程工期。很多人凭直觉选“对”因为关键路径决定最短工期缩短它当然有用。但这里有个前提被忽略了——缩短之后这条路径可能不再是关键路径另一条路径变成了新的关键路径总工期由新的关键路径决定。所以“一定”这个词就是陷阱。正确的分析思路是缩短关键路径上的活动时间后需要重新计算网络图看是否有其他路径的时长超过了缩短后的原关键路径。如果没有工期确实缩短如果有工期由新的最长路径决定可能不变甚至变化幅度小于预期。注意这类题的通用套路是找“一定”“必然”“所有”这类绝对化表述数据结构里绝大多数绝对化判断都是错的除非是定义层面的陈述。2.2 顺序查找ASL的适用条件判断题第二题说顺序查找不成功的平均查找长度是(n1)/2。这个结论本身没错但它有一个隐含条件查找每个元素的概率相等且不成功查找发生在所有可能的查找位置等概率的情况下。如果题目没有明确这个前提严格来说这个结论不能直接套用。实际考试中这类题通常考的是“你是否知道公式的适用边界”。顺序查找成功时的ASL确实是(n1)/2不成功时是n1需要比较n1次才能确定不在表中这两个别搞混。2.3 出栈序列的合法性判断判断题第三题给出进栈序列1到6问2,3,5,1,6,4是否可能是出栈序列。判断方法不复杂但手工模拟容易乱。我一般用“栈模拟法”按进栈序列依次压栈每次压入后检查栈顶是否等于当前需要的出栈元素如果是就弹出继续检查下一个出栈元素。具体到这个序列压1压2栈顶2匹配弹出2压3栈顶3匹配弹出3压4压5栈顶5匹配弹出5此时栈内是1,4下一个需要弹出1但栈顶是4不匹配继续压6栈顶6匹配弹出6此时栈内是1,4需要弹出4但栈顶是1不匹配。最终无法完成所以这个序列不合法。2.4 二叉树遍历的反推判断题第五题给了中序ABCDE和先序CABED问后序是否是BADCE。反推方法是先序的第一个C是根在中序中找到C左边AB是左子树右边DE是右子树。左子树先序是AB中序是AB所以A是根B是右孩子右子树先序是ED中序是DE所以E是根D是左孩子。整棵树的后序应该是B A D E C不是BADCE。这类题的关键是每一步都要在两种序列中同步定位不能只凭感觉画。2.5 递归函数的调用次数简答题第二题的函数fun(x,n)计算x的n次幂递归终止条件是n1。fun(2,5)的计算过程是2×fun(2,4)2×2×fun(2,3)…总共发生4次递归调用n从5降到1每次减1调用次数是n-1。如果问“最多发生几次”答案取决于n的初始值递归深度是n-1。这里容易错的地方是把“递归调用次数”和“乘法次数”搞混乘法确实做了n-1次但递归调用也是n-1次因为每次调用只做一次乘法然后返回。3. 应用分析题手算过程的标准化模板3.1 二路归并排序的每趟结果题目给的序列是{15,5,16,2,25,8,20,9,18,12}要求写出二路归并每一趟的结果。二路归并的“一趟”指的是把当前所有长度为L的有序段两两合并成长度为2L的有序段。初始每个元素是长度1的有序段。第一趟两两合并相邻元素得到{5,15},{2,16},{8,25},{9,20},{12,18}写完整序列就是5,15,2,16,8,25,9,20,12,18。第二趟把长度2的有序段两两合并。{5,15}和{2,16}合并成{2,5,15,16}{8,25}和{9,20}合并成{8,9,20,25}{12,18}单独保留。序列变成2,5,15,16,8,9,20,25,12,18。第三趟{2,5,15,16}和{8,9,20,25}合并成{2,5,8,9,15,16,20,25}{12,18}保留。序列变成2,5,8,9,15,16,20,25,12,18。第四趟最后两段合并得到2,5,8,9,12,15,16,18,20,25。提示写归并每趟结果时建议把每段用花括号标出来再合并直接写最终序列容易漏掉中间步骤的分数。3.2 普里姆算法与克鲁斯卡尔算法的执行过程题目给了一个带权无向图以顶点0为起点构造最小生成树。普里姆算法的核心是维护一个已选顶点集合每次从连接已选集合和未选集合的边中选权值最小的。执行过程需要逐步写出每次选择的边和加入的顶点。克鲁斯卡尔算法则是把所有边按权值排序从小到大依次选取如果加入的边不构成环就保留否则跳过。这两种算法的执行过程在答题时要注意普里姆算法必须从指定起点开始每一步的选择依赖于当前已选集合克鲁斯卡尔算法不依赖起点全局按边权排序。考试中常见的失分点是普里姆算法没有从指定顶点开始或者克鲁斯卡尔算法选边时没有检查环。3.3 二叉排序树的构造与ASL计算先序序列{12,5,2,8,6,10,16,15,18,20}构造二叉排序树方法是按先序顺序依次插入。12是根5比12小放左边2比5小放左边8比5大放右边6比8小放左边10比8大放右边16比12大放右边15比16小放左边18比16大放右边20比18大放右边。中序遍历结果就是所有元素升序排列2,5,6,8,10,12,15,16,18,20。等概率下查找成功的ASL计算方法是每个节点的查找长度等于它的层数把所有节点的层数加起来除以节点总数。查找不成功的ASL需要统计所有外部空指针位置的查找长度通常画图时在每个空指针处标出比较次数。3.4 平衡二叉树的插入与调整序列{4,5,7,2,1,3,6}构建平衡二叉树关键是每次插入后检查平衡因子如果不平衡就判断调整类型。插入4根节点。插入54的右孩子。插入7此时4的平衡因子变成-2属于RR型需要左旋5变成根4变成5的左孩子7是5的右孩子。继续插入2放在4的左边。插入14的平衡因子变成2属于LL型右旋2变成根1是2的左孩子4是2的右孩子。插入3放在4的左边。插入6放在7的左边。每一步都要画出调整前后的树形并标注调整类型LL、RR、LR、RL。3.5 哈希表构造与ASL计算关键字{32,13,49,24,38,21,4,12}哈希函数H(key)key%7地址空间0到9线性探查法解决冲突。计算每个关键字的初始哈希地址32%7413%7649%7024%7338%73冲突探查4再探查521%70冲突探查14%74冲突探查5再探查6再探查712%75冲突探查6再探查7再探查8。最终哈希表地址0放49地址1放21地址2空地址3放24地址4放32地址5放38地址6放13地址7放4地址8放12地址9空。查找成功的ASL每个元素的比较次数分别是1,1,1,1,2,2,4,4总和16除以8得2。查找失败的ASL需要从每个地址出发探查到空地址的比较次数通常按哈希函数可能映射到的地址计算。4. 程序设计题两道算法题的递归模型与链表操作4.1 求二叉树度为2的结点个数题目要求设计算法求二叉树中度为2的结点个数结点类型已经给出。递归模型的设计思路是如果当前结点为空返回0如果当前结点左右孩子都不为空返回1加上左子树的结果加上右子树的结果否则返回左子树结果加右子树结果。typedef struct node { char data; struct node *lchild, *rchild; } BTNode; int countDegree2(BTNode *b) { if (b NULL) return 0; // 空结点度为2的结点数为0 if (b-lchild ! NULL b-rchild ! NULL) return 1 countDegree2(b-lchild) countDegree2(b-rchild); else return countDegree2(b-lchild) countDegree2(b-rchild); }递归模型的核心是度为2的结点贡献1度为1或0的结点贡献0然后递归累加左右子树。参数b是当前子树根节点返回值是这棵子树中度为2的结点总数。时间复杂度O(n)空间复杂度O(h)h是树高。4.2 删除单链表中值最小的所有结点题目要求删除带头结点单链表L中结点值最小的所有结点可能有多个。思路是先遍历一遍找到最小值再遍历一遍删除所有等于最小值的结点。typedef struct LNode { int data; struct LNode *next; } LNode, *LinkList; void DelNode(LinkList L) { if (L-next NULL) return; // 空表直接返回 int min L-next-data; LNode *p L-next-next; while (p ! NULL) { // 第一遍找最小值 if (p-data min) min p-data; p p-next; } LNode *pre L, *q L-next; while (q ! NULL) { // 第二遍删除所有最小值结点 if (q-data min) { pre-next q-next; free(q); q pre-next; } else { pre q; q q-next; } } }第一遍遍历确定最小值第二遍用pre指针维护前驱遇到等于最小值的结点就跳过并释放。注意删除后q要更新为pre-next不能直接qq-next因为q已经被释放了。这个算法的时间复杂度是O(n)空间复杂度O(1)。5. 从这份卷子反推复习策略三个我踩过的坑5.1 别把“看懂”当成“会写”我刚开始复习数据结构的时候看一遍教材觉得什么都懂了一合上书手写归并排序的每趟结果就卡住。这份卷子里的应用分析题全是过程推导不是选择题你必须能一步一步写出来。我的建议是拿一张白纸把每道题的推导过程完整写一遍写完对照答案看哪一步跳了或者错了。特别是普里姆算法和克鲁斯卡尔算法画图比写字更重要边画边标序号。5.2 递归题先写递归模型再写代码程序设计题里的二叉树度为2结点个数很多人直接写代码结果边界条件漏了。正确的顺序是先写出递归模型f(b) 0 当b为空f(b) 1 f(b-lchild) f(b-rchild) 当左右孩子都存在f(b) f(b-lchild) f(b-rchild) 其他情况。模型写清楚了代码就是翻译。链表删除最小值那道题关键是两遍遍历第一遍找最小值第二遍删。不要试图一遍搞定容易出错。5.3 哈希表的ASL计算要分清成功和不成功哈希表那道题查找成功的ASL是每个元素的比较次数之和除以元素个数查找不成功的ASL是从每个哈希地址出发到第一个空地址的比较次数之和除以哈希地址总数这里是10不是7。很多人把不成功的分母也写成元素个数直接翻车。另外线性探查法删除元素时不能直接置空否则会截断后续元素的查找路径通常用标记法处理。5.4 平衡二叉树的调整类型判断平衡二叉树的四种调整类型LL、RR、LR、RL判断方法是看插入位置相对于最小不平衡子树根节点的方向。LL是左孩子的左子树插入RR是右孩子的右子树插入LR是左孩子的右子树插入RL是右孩子的左子树插入。我习惯在每次插入后从插入点往上找第一个平衡因子绝对值大于1的节点然后判断类型。调整的时候注意旋转后子树的根节点要正确连接到原父节点上。5.5 出栈序列的快速验证出栈序列的合法性判断除了栈模拟法还有一个经验如果出栈序列中某个元素后面出现了比它小且不是按降序排列的元素基本可以判定不合法。但这个方法不是绝对可靠考试时还是老老实实用栈模拟一步一步压弹别图快。这份卷子的价值在于它把数据结构的核心考点都覆盖了而且题型分布合理。如果你能把这七页纸上的每道题都独立做一遍对照答案找到自己的薄弱环节期末复习的效率会比翻教材高很多。我后来每次带人复习数据结构都让他们先做一套完整的卷子再针对错题回去补知识点比从头看书快得多。希望帮到你。本文还有配套的精品资源点击获取