【USACO题库】3.4.2 American Heritage美国血统

题目大意:

根据一颗树的中序遍历和前序遍历求出这棵树的后序遍历。


样例输入:

ABEDFCHG

CBADEFGH

样例输出:

AEFDBHGC


这道题我先讲一下自己的建树方法:

我们知道一颗树的中序遍历,前序遍历,后序遍历的顺序是这样子的:

左根右

根左右

左右根


所以我们可以根据前序遍历找出当前这颗树的根。例如样例中,这颗树的根是C,则这颗树的左右子树分别为——ABEDF,HG——这是根据中序遍历得出来的结果,然后我们可以再根据前序遍历的第2个字母得出左子树的根为B,然后这颗树的左右子树分别为——A,EDF。以此类推——最后我们可以得到如下的一棵树——【USACO题库】3.4.2 American Heritage美国血统_第1张图片从这里我们就可以得出后序遍历为AEFDBHHC了。

具体解释在代码里解释:

var
        s1,s2:string;
        len,k,x:longint;
        a:array['A'..'Z',1..2] of char;
procedure dfs(s:string; t:longint);
var
        w:longint;
begin
        inc(k);<span style="white-space:pre">				</span>//这里是数当前分了几段了,k等于多少的时候就是
        w:=pos(s2[k],s);<span style="white-space:pre">		</span>//这里是找当前需要分解的s子串的根节点在哪里,方便往子串的两端分解。
        if length(copy(s,1,w-1))>0 then<span style="white-space:pre">	</span>//如果左边可以分解,则往左边分
        begin
                a[s1[t],1]:=s2[k+1];<span style="white-space:pre">	</span>//t表示当前分解到s1串的哪个位置,s2[k+1]就是下次分解的根节点,也是需要记录的节点。
                dfs(copy(s,1,w-1),pos(s2[k+1],s1));<span style="white-space:pre">	</span>//这里的t更新为这个数是方便下次记录。
        end;
        if length(copy(s,w+1,length(s)-w))>0 then
        begin
                a[s1[t],2]:=s2[k+1];
                dfs(copy(s,w+1,length(s)-w),pos(s2[k+1],s1));
        end;
end;
procedure print(ch:char);<span style="white-space:pre">		</span>//后序遍历输出
begin
        if a[ch,1] in ['A'..'Z'] then
        begin
                print(a[ch,1]);
                write(a[ch,1]);
        end;
        if a[ch,2] in ['A'..'Z'] then
        begin
                print(a[ch,2]);
                write(a[ch,2]);
        end;
end;
begin
        readln(s1);
        readln(s2);
        len:=length(s1);

        dfs(s1,pos(s2[1],s1));
        print(s2[1]);
        writeln(s2[1]);
end.


当然还有另一种方法,也就是在构树的时候直接输出后序遍历:

var
        s1,s2:string;
procedure dfs(x,y:string);
var
        w:longint;
begin
        if length(x)<=1 then
                write(x[1])<span style="white-space:pre">		</span>//这里是输出“左右”
        else
        begin
                w:=pos(x[1],y);<span style="white-space:pre">		</span>//查找当前子串的根节点
                dfs(copy(x,2,w-1),copy(y,1,w-1));<span style="white-space:pre">	</span>//往根节点的两边分。
                dfs(copy(x,w+1,length(x)-w),copy(y,w+1,length(y)-w));
                write(x[1]);<span style="white-space:pre">		</span>//这里是输出“根”
        end;
end;
begin
        readln(s1);
        readln(s2);
        dfs(s2,s1);
end.


你可能感兴趣的:(【USACO题库】3.4.2 American Heritage美国血统)