codevs1013 求先序排列 string黑科技[三星]

来源:互联网 发布:mysql的EXPLAIN用法 编辑:程序博客网 时间:2024/04/30 10:50

题目链接:戳我

题目描述 Description

给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,长度<=8)。

输入描述 Input Description

两个字符串,分别是中序和后序(每行一个)

输出描述 Output Description

一个字符串,先序

样例输入 Sample Input

BADC
BDCA

样例输出 Sample Output

ABCD

首先要了解与树的序遍历,先序遍历就是满足根节点->左子树->右子树的性质,中序遍历就是满足左子树->根节点->右子树的性质,后序遍历就是满足左子树->右子树->根节点的顺序。‘

如果还是不理解可以看一下这个题的样例。——————


如果你理解了上述性质,那么聪明的你一定想到根节点再三个序列中的地位,后序遍历最后一个点是根节点,中序遍历中间那个点是根节点。

根据这个性质我们可以递归处理出前序遍历:
用数组mid[lm..rm]和post[tp..rp]存储给定的中序和后序序列。易知post[rp]为根结点,创建二叉树的根结点t,设t.data = post[rp];遍历mid,寻找根结点post[rp]的下标pos,则mid[lm..pos-1]为左子树序列,mid[pos+1..rm]为右子树序列;左子树序列的长度lenL= pos - lm,右子树序列的长度lenR= rm - pos。
很明显,若pos == lm,则lenL = 0,说明根结点无左子树;若pos == rm,则lenR = 0,说明根结点无右子树;
根据后序序列的规律,可以知道根结点t的左子树的后序排列为post[lp..lp+lenL-1];
根结点t的右子树的后序排列为post[lp+lenL..rp-1]。
采用同样的方法递归构造根结点t的左右子树。

这里方法介绍完毕,但是具体实现会不会非常恶心呢?
不怕,我们有string大法,C++的string真的非常好用,但是真的非常慢23333(不用问问什么吧

这里介绍一下assign函数(自己怎么理解的怎么来说啦~)
assign(s,start,size);
s表示从s中复制,start表示的是s中的坐标,表示从start位置开始复制,size表示复制的大小,即从start开始往后多少位。
用法: string s; s.assign(ss,0,ss.size());

递归函数具体写法:

void find(string smid,string slst){    string str1,str2,str3,str4;    int m = smid.find(slst[slst.size()-1]);//在中序遍历中找根节点的位置,计做m    str1.assign(smid,0,m);//中序遍历左子树    str2.assign(smid,m+1,smid.size()-m-1);//m位置是根节点,要从m+1开始复制    str3.assign(slst,0,str1.size());//后序遍历中左子树    str4.assign(slst,str1.size(),str2.size());//后序遍历中右子树    cout<<slst[slst.size()-1];//输出递归当前的根节点,因为前序遍历先输出根节点    if(str1.size())        find(str1,str3);//如果左子树不是空的,那就递归左子树    if(str2.size())        find(str2,str4);//如果右子树不是空的,那就递归右子树}

完整代码~

#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<deque>#include<algorithm>#include<cmath>using namespace std;string s1,s2;void find(string smid,string slst){    string str1,str2,str3,str4;    int m = smid.find(slst[slst.size()-1]);    str1.assign(smid,0,m);    str2.assign(smid,m+1,smid.size()-m-1);    str3.assign(slst,0,str1.size());    str4.assign(slst,str1.size(),str2.size());    cout<<slst[slst.size()-1];    if(str1.size())        find(str1,str3);    if(str2.size())        find(str2,str4);}int main(){    cin>>s1>>s2;    find(s1,s2);    return 0;}
0 0