[JLU] 数据结构与算法上机题解思路分享-第二次上机 吉林大学

前言

首先,请务必自己尽全力尝试实现题目,直接看成品代码,思维就被拘束了,也很容易被查重。

这里只是思路解析的博客,代码仓库在 JLU_Data_Structures_Record

希望你能在这里找到你想要的:)

正文


A 二叉树的创建与遍历

分数 10
作者 朱允刚
单位 吉林大学
通过带空指针信息的先根序列(亦称先序序列)创建二叉树,并进行先根(先序)、中根(中序)、后根(后序)遍历。二叉树结点数据域值为不等于0的整数(可能是正数也可能是负数),空指针用0表示,例如1 5 8 0 0 0 6 0 0表示如下图的二叉树。

输入格式:
输入为一组用空格间隔的整数,表示带空指针信息的二叉树先根序列。其中空指针信息用0表示。二叉树结点个数不超过150000,高度不超过6000。输入数据保证二叉树各结点数据值互不相等。

输出格式:
输出为3行整数,每个整数后一个空格。第1行为该二叉树的先根序列,第2行为中根序列,第3行为后根序列。

输入样例:
1 5 8 0 0 0 6 0 0
输出样例:
1 5 8 6
8 5 1 6
8 5 6 1
代码长度限制
16 KB
时间限制
200 ms
内存限制
20 MB


这道题没什么好解析的,从先根序列造二叉树,可以采用递归的方法,0则结束,否则就以该值创节点,并进入左节点的函数和右节点的函数。


B 二叉树查找结点及父结点

分数 10
作者 朱允刚
单位 吉林大学
编写程序在二叉树中查找给定结点及父结点。二叉树结点的数据域值不等于0的整数。

输入格式:
输入第1行为一组用空格间隔的整数,表示带空指针信息的二叉树先根序列,其中空指针用0表示。例如1 5 8 0 0 0 6 0 0表示如下图的二叉树。第2行为整数m,表示查询个数。接下来m行,每行为一个不等于0的整数K,表示要查找的结点的数据值。m不超过100,二叉树结点个数不超过150000,高度不超过6000。输入数据保证二叉树各结点数据值互不相等。

输出格式:
输出为m行,每行1个整数,表示被查找结点K的父结点数据值,若二叉树中无结点K或结点K无父结点,则输出0。

输入样例:
1 5 8 0 0 0 6 0 0
3
8
1
6
输出样例:
5
0
1
代码长度限制
16 KB
时间限制
300 ms
内存限制
20 MB


造树的函数可以复用上一题,本体考察的查找,更没有啥可以说的,你可以任选先、中、后三种顺序都可以


C 二叉树删除子树

分数 10
作者 朱允刚
单位 吉林大学
编写程序对给定二叉树执行若干次删除子树操作,输出每次删除子树后剩余二叉树的中根序列。二叉树结点的数据域值为不等于0的整数。每次删除操作是在上一次删除操作后剩下的二叉树上执行。

输入格式:
输入第1行为一组用空格间隔的整数,表示带空指针信息的二叉树先根序列,其中空指针信息用0表示。例如1 5 8 0 0 0 6 0 0表示如下图的二叉树。第2行为整数m,表示要进行的删除操作次数。接下来m行,每行一个不等于0的整数K,表示要删除以K为根的子树。m不超过100,二叉树结点个数不超过5000。输入数据保证各结点数据值互不相等,且删除子树后二叉树不为空。

输出格式:
输出为m行,每行为一组整数,表示执行删除操作后剩余二叉树的中根序列(中根序列中每个整数后一个空格)。若要删除的子树不在当前二叉树中,则该行输出0(0后无空格)。

输入样例:
1 5 8 0 0 0 6 0 0
3
5
8
6
输出样例:
1 6
0
1
代码长度限制
16 KB
时间限制
100 ms
内存限制
10 MB


此题可以分解为两部分,第一部分是找到要删的点,第二部分是执行删除。寻找部分就是第二题,那么我们实际上可以专注于如何执行二叉树的删除了。

那么什么是删除呢?可表现为其父节点对应指针为空,那么空间要不要释放呢?随你喜欢,毕竟答案检验是遍历,与内存无关:)所以把父节点对应指针置空即可。

整体的构造是递归,若没找到则向两子树找,找到就删除对应子树,没找到回报个0


D 重建二叉树

分数 30
作者 朱允刚
单位 吉林大学
给定非空二叉树的中根序列和后根序列,请编写程序创建该二叉树,计算其高度和先根序列;如给定的中根和后根序列不合法,则亦能识别。

输入格式:
输入包含多组数据(不超过10组),每组为两行字符串,第一行表示某二叉树的后根序列,第二行表示其中根序列。结点的值均为A-Z的大写字母,故二叉树结点个数不超过26,且保证输入的两个序列都是结点的全排列,但不一定是合法的中根和后根序列。输入保证不是空二叉树。

输出格式:
对于每组数据,如果输入的序列不合法(不是同一棵树的中根序列和后根序列),则输出INVALID;若输入序列合法,输出为两行,第一行为一个整数,表示该二叉树的高度,第二行为一个字符串,表示该二叉树的先根序列。

输入样例1:
CEFDBHGA
CBEDFAGH
CBEDFAGH
CEFDBHGA
BCA
CAB

输出样例1:
3
ABCDEFGH
INVALID
INVALID

代码长度限制
16 KB
时间限制
50 ms
内存限制
64 MB


本题也是书上有的内容此处就简单叙述下要点,中根和后根序列分别给了不同的信息,后根的最后一个表示该树的中点,也就是最上面那个,根据中点就可以从中根序列中找到该树的左子树有什么点,右子树有什么点。

而这样的分割可以不断递归,毕竟一个二叉树的左子树也是二叉树,只要不断地将子树的中后序列分割出来,总有左右子树只剩一点或者无点的情况,然后再不断组装回去,最后就得到了二叉树


E 二叉树路径和

分数 20
作者 朱允刚
单位 吉林大学
编写程序找出二叉树中和最大的路径,二叉树结点为不等于0的整数。本题的“路径”限定为以根结点为起点,以叶结点为终点的路径。路径的和,即该路径所包含的所有结点的数据值之和。

输入格式:
输入为一组用空格间隔的整数,个数不超过100个,表示带空指针信息的二叉树先根序列。

输出格式:
输出为两行,第一行为该二叉树路径和的最大值,第二行为一组整数,每个整数后一个空格,即该最大路径包含的结点值(按从根的叶的顺序),如果存在多条满足条件路径,则输出最左边一条。

输入样例1:
1 2 0 0 3 0 0
输出样例1:
4
1 3
输入样例2:
-1 2 0 0 3 0 0
输出样例2:
2
-1 3
代码长度限制
16 KB
时间限制
50 ms
内存限制
64 MB


像这种寻找一条最优路的方法,基础办法有深度优先算法DFS或广度优先算法BFS。

以DFS为例,大致就是用栈(其实就是一个数组加指针)来记录路径,然后遍历一遍二叉树,以DFS或BFS的方式,到底时与已有路径记录比较,保留更大的


F 哈夫曼树编码

此题不做分享,毕竟陆爻齐也差一个点,没资格说话


G S遍历

分数 30
作者 朱允刚
单位 吉林大学
二叉树的“S遍历”定义为从根结点开始,先自右向左遍历,然后下一层自左向右遍历,再下一层自右向左遍历,以此类推…。例如下图所示二叉树的S遍历序列为1 2 3 6 5 4 7 8。现给定一棵非空二叉树,结点数据域值为互不相等且不等于0的正整数,同时给定两个正整数a和b,请编写程序输出结点a和b间的S遍历序列。

555.jpg

输入格式:
输入第一行为1组用空格间隔的正整数,表示带空指针信息的二叉树先根序列,二叉树结点个数不超过150000,高度不超过5000。第二行为两个正整数a和b,含义如题目所述,保证a和b一定在二叉树中,且在S遍历序列中a在b的前边。

输出格式:
输出为一行整数,每个整数后一个空格,表示数据值为a和b的两个结点间的S遍历序列。

输入样例1:
1 2 4 0 0 0 3 5 7 0 0 8 0 0 6 0 0
1 8
输出样例1:
1 2 3 6 5 4 7 8
输入样例2:
1 2 0 4 0 7 0 0 3 5 0 0 6 8 20 0 0 21 0 0 0
6 8
输出样例2:
6 5 4 7 8
输入样例3:
1 2 0 3 4 5 0 0 6 0 0 0 7 0 8 9 10 0 0 11 0 0 0
1 11
输出样例3:
1 2 7 8 3 4 9 11
输入样例4:
2 4 3 0 0 8 0 0 10 5 7 9 0 0 1 0 0 17 0 0 6 0 0
2 9
输出样例4:
2 4 10 6 5 8 3 7 17 1 9
数据规模:
测试点0-2、5-9:结点个数≤50,树高≤20
测试点3:4500≤结点个数≤5500,4000≤树高≤5000
测试点4:130000≤结点个数≤150000,10≤树高≤20

代码长度限制
16 KB
时间限制
100 ms
内存限制
20 MB


此题看似是一个十分繁琐的搜索,但其实就是考察对于基本数据结构栈和队列的用法。

陆爻齐采用了栈来解决该问题,也就是用两个栈,分别存储向左和向右遍历时存储的点,然后向左向右分别用不同的顺序把点加进栈,模拟出所谓的S型


H 衣服挂游戏

分数 20
作者 朱允刚
单位 吉林大学
有n个衣服挂,编号为1至n,初始时按顺序挂在一个晾衣杆上,每个衣挂自成一列(即相当于有n列,每列只含一个衣挂)。

1.jpg

爸爸让艾迪做如下操作“x y”,表示将衣挂x所在的列放在衣挂y所在的列下面,即把x所在列的第一个衣挂,挂在y所在列的最下面的衣挂下面,如果x和y已在同一列里,则忽略该操作。例如上图执行操作“3 5”后,得到下图:

2.jpg

再执行操作“3 2”后,得到下图:

3.jpg

爸爸给出一系列指令,请编写程序,输出艾迪完成爸爸的所有操作后,每个衣挂所在的列的第一个衣挂的编号。

输入格式:
每个测试点包含多组测试数据,第一行1个整数 T ,表示测试数据组数。对于每组数据,第一行两个整数 n 和 m,分别表示衣挂个数和操作次数。接下来 m 行,每行两个整数x和y,表示爸爸让艾迪执行的一个操作。T≤5,1≤n, m≤30000,1≤x, y≤n。

输出格式:
输出为T 行,每行为 n个整数a1 a2 … an ,每个整数后一个空格,ai(1≤i≤n)表示衣挂i所在列的第一个衣挂的编号。

输入样例:
2
4 2
2 1
4 3
5 4
1 2
2 3
4 5
1 3

输出样例:
1 1 3 3
3 3 3 5 5

代码长度限制
16 KB
时间限制
80 ms
内存限制
64 MB


该题的本质是考察并查集的创建和使用,像这种很喜欢溯源的,并查集往往都能比较好的解决。

再简单说下陆爻齐认为的并查集吧,并查集往往用数组实现,用下标表示其编号,而存储的数字则为其父亲的编号,也就是父节点的下标。

题中正好n个衣架,编号1-n,正好对应数组,把x挂y上,完全可以把x上的数字改成y;这是x无父节点的情况,若x有父节点,当然先要追溯到其曾曾祖父,把老人家挂y上。


小结

这次上机主要考查了二叉树的创建、查找、删除等,还有并查集的使用,利用上机题巩固所学不失为一种好方法:)

posted @ 2024-07-01 22:05  陆爻齐  阅读(7)  评论(0编辑  收藏  举报