二叉树的恢复
说明:这是重庆交通大学第10届大学生程序设计大赛的题目,应该只有本校生能提交。
题目
Lucy最近正在学习数据结构中的二叉树,为了更好学习二叉树的几种遍历,Lucy常常自己随机写一些二叉树。比如说下面这样的一棵二叉树。
但是计算机是不能输入这样的图形的,只能用一组序列来保存二叉树:前序遍历序列、后序遍历序列、或中序遍历序列。前序序列,节点访问顺序为:根,左子树,右子树。中序序列,节点访问顺序为:左子树,根,右子树。后序序列,节点访问顺序为:根,左子树,右子树。
如下图,前序遍历序列为ABDEGHJCFI,中序遍历序列为DBGEHJACIF,而后序遍历序列为DGJHEBIFCA。
在本题中,输入一棵二叉树的前序和后序遍历序列,再输入n个长度相等的序列,判断这些序列是否可能为该二叉树的中序遍历序列。
输入描述:
输入数据第一行为一棵二叉树的前序遍历序列和后序遍历序列,用空格隔开,每个序列由26个大写字母组成且每个节点的字母不重复,所以两个遍历序列的长度都不超过26。第二行为正整数n,$n \le 10$,接下来有n行,每行是一个由大写字母构成的序列,这n个序列互不相同,保证长度和第一行中的两个序列长度相等,且保证出现的字母和第一行中的两个序列出现的字母一样。
输出描述:
如果n个待判定的序列中存在对应二叉树的中序遍历序列,输出它们的序号,序号从1开始计起,按从小到大的顺序输出,每个序号占一行。如果n个待判定的序列都不是中序遍历序列,输出none。
注意,由前序遍历序列和后序遍历序列不能确定一棵二叉树,所以n个序列中可能有多个是中序遍历序列。
样例输入1:
ABDEGHJCFI DGJHEBIFCA
3
ADBGEHJCIF
DGBEHJACIF
DBGEHJACIF
样例输出1:
3
样例输入2:
ABDEGHJCFI DGJHEBIFCA
3
ADBGEHJCIF
DGBEHJACIF
DBGEHJAICF
样例输出2:
none
实现思路
「背景性质」:
二叉树有一个性质是:可以由前序遍历和中序遍历重新构建二叉树。或者由后序遍历和中序遍历重新构建二叉树。
简单说明一下这个性质:(说明前序+中序。后序+中序同理)
前序遍历:根节点,左子树,右子树
中序遍历:左子树,根节点,右子树
这里我们知道,树的根节点一定是前序遍历中的第一个元素。那么我们把这个元素放到中序遍历中,这个元素左边的元素就是这颗树的根节点的左子树,同理,右边的元素就是右子树。
接着,去掉第一个元素的前序遍历的第一个元素一定是子树(可能没有左子树)的根节点。然后再从中序遍历得到的左子树序列和右子树序列中寻找值。
如此其实可以得出是一个递归的过程。
「本题思路」:
这道题和 中序和后序重构二叉树 的题型是差不多的,只是这道题稍微绕一点。
后序遍历和中序遍历也能构建一颗二叉树,我这里选用前序+中序(读者可以尝试自己用后序+中序实现一下)。
读入题目的前序遍历序列和后序遍历序列后。再读入中序遍历序列,使用这个中序遍历序列号前序遍历序列结合重构一颗二叉树。
再对这颗重构好的二叉树进行后序遍历,比较是否和题目中的后序遍历序列相同。相同则加一。
具体实现看代码(几乎每行都有注释)。
注意:题目中的数据不保证一定可以构成一颗树。代码中要判断。
实现代码
1 |
|
最终提交结果: