题目内容
给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,长度≤8)。
输入输出
输入:2行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列。
BADC
BDCA
输出:1行,表示一棵二叉树的先序。
ABCD
其他样例:
输入:
CBAFEGD
CFGEADB
输出:
BCDAEFG
输入:
DCBA
DCBA
输出:
ABCD
Code
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
string s1,s2,s3="";
/*
找到中序序列中的根
参数:当前数在中序序列的范围[midl,midr] 后序序列的范围[backl,backr] 字符串s
根据后序序列末尾确定根,在中序序列中查找该根的位置,确定左右子树的个数
*/
void searchtree(int midl, int midr, int backl, int backr, string &s3){
if(midl > midr || backl > backr) return;
s3 += s2[backr]; //后序序列的末尾为根结点
int p = midl;
while(s1[p] != s2[backr]) p++; //找到中序序列中根结点在的位置
int cnt = p - midl; //左子树结点的个数 = 跟结点的位置-初始位置
searchtree(midl, p-1, backl, backl + cnt -1, s3); //左子树,分别在两个序列中的对应范围
searchtree(p+1, midr, backl + cnt, backr-1, s3); //右子树,分别在两个序列中的对应范围
}
int main(){
cin >> s1;
cin >> s2;
searchtree(0, s1.size()-1, 0, s1.size()-1, s3);
cout << s3 << endl;
return 0;
}
/*
找到中序序列中的根
参数:当前的根,中序序列,当前子树的范围[a,b],当前根的位置,后序序列,结果序列
根据后序序列确定在中序序列中的子树的根在哪里
该方法不严谨,只能通过80%样例,因为需要控制后序遍历中的范围。
*/
// int searchx(string s, char c){ //在字符串s中[a,b]的位置寻找字符c的位置
// for(int i = 0; i <= s.size()-1; i++){
// if(s[i] == c) return i;
// }
// return -1;
// }
// void searchtree(char root, int a, int b, int rootx, string &s3){
// if(a > b || b >= s2.size() || a < 0 ) return; //如果区间已经左>右,说明区间内已经处理完毕,直接返回,否则会死循环
// if(a == b){
// s3 += s1[a];
// return;
// }
// s3 += root; //先序序列先把根结点加进去
// cout <<"111 " << s3 << endl;
// if(a == rootx) return; //如果左边界就是当前根结点,则不需要再搜索左子树
// else{
// if(b != rootx){
// char ch = s1[rootx+1]; //中序序列中右子树第一个点为分割后序序列中前后子树的部分
// int rootxl = searchx(s2, ch)-1; //后序序列中左子树的根的位置
// char newrootl = s2[rootxl]; //在后序序列中找到左子树新的根的字符
// int xl = searchx(s1, newrootl); //在中序序列中左子树的根的位置
// searchtree(newrootl, a, rootx-1, xl, s3);
// }
// else{ //如果右边界是根结点,左子树的根为后序序列的当前根结点前一位
// searchtree(s2[rootx-1], a, rootx-1, searchx(s1,s2[rootx-1]), s3);
// }
// }
// if(b == rootx) return; 如果右边界就是当前根结点,则不需要再搜索右子树
// else{
// int rootxr = searchx(s2, root)-1;
// char newrootr = s2[rootxr] ; //在后序序列中找到右子树新的根的字符
// int xr = searchx(s1, newrootr);
// searchtree(newrootr, rootx+1, b, xr, s3);
// }
// return;
// }
TIPS
- 充分利用序列条件,遵循从后序找根,从中序找范围的准则进行递归。
- 注意细节,找范围时个数,控制边界等。
- 注意边界。