题目描述
给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,长度≤8)。
输入格式
2行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列。
输出格式
1行,表示一棵二叉树的先序。
解题思路
这是一道二叉树的题目,当时老师是布置过这个题目的,但是我当时是用递归做的,但是我当时年轻,老师问了一句如果数据量10000000个,你又怎么处理呢,我当时提出了一个解法,好像和二叉排序树相关,转眼半年过去了,原解法已经忘了,现在想的这个解法也许是新解法?
我们可以每次对中序序列的
l
1
∼
r
1
l_1 \sim r_1
l1∼r1的范围和后序序列的
l
2
∼
r
2
l_2 \sim r_2
l2∼r2的范围内搜索,在中序序列中找到后序序列中
r
2
r_2
r2位置上的节点,假设它在中序序列中对应下标为p,中序序列裂变成
l
1
∼
(
p
−
1
)
l_1\sim (p-1)
l1∼(p−1)和
(
p
+
1
)
∼
r
1
(p+1) \sim r_1
(p+1)∼r1两部分,后序遍历裂变成
l
2
∼
(
l
2
+
p
−
1
−
l
1
)
l_2\sim (l_2+p-1-l_1)
l2∼(l2+p−1−l1)和
(
l
2
+
p
−
l
1
)
∼
(
r
2
−
1
)
(l_2+p-l_1)\sim (r2-1)
(l2+p−l1)∼(r2−1)两部分,然后继续向下分裂,直到不能分裂为止,注意,每次分裂时,都要把p位置上节点的值输出一次,因为后序序列的最后一个节点就是先序序列的第一个节点。这题数据量特别小,递归应该能过,但是我害怕10000000的数据量,所以我选择非递归做法,并且用数组模拟了栈。
Talking is cheap,show you my code.
代码
#include<iostream>
#include<string>
using namespace std;
string str1, str2;//str1:中序,str2:后序
int node[10][4];
int main() {
cin >> str1 >> str2;
int s = str1.size();
int num = 0;
node[num][0] = 0;
node[num][1] = --s;
node[num][2] = 0;
node[num++][3] = s;
while (num) {
int l1 = node[--num][0];
int r1 = node[num][1];
int l2 = node[num][2];
int r2 = node[num][3];
int begin = l1;
while (str1[begin] != str2[r2]) {
begin++;
}
cout << str2[r2];
if (r1 > begin) {
node[num][0] = begin + 1;
node[num][1] = r1;
node[num][2] = l2 + begin - l1;
node[num++][3] = --r2;
}
if (begin > l1) {
node[num][0] = l1;
node[num][1] = begin - 1;
node[num][2] = l2;
node[num++][3] = l2 + begin - 1 - l1;
}
}
return 0;
}