資訊學奧賽一本通 二叉樹遍歷
阿新 • • 發佈:2019-01-02
題目是:
【題目描述】
輸入一棵二叉樹的先序和中序遍歷序列,輸出其後序遍歷序列。
【輸入】
共兩行,第一行一個字串,表示樹的先序遍歷,第二行一個字串,表示樹的中序遍歷。樹的結點一律用小寫字母表示。
【輸出】
一行,表示樹的後序遍歷序列。
【輸入樣例】
abdec dbeac
【輸出樣例】
debca
額,真丟臉啊,這道題從11月7日卡在腦袋裡卡到了現在(mmp硬是沒有看題解);
不過老李講的還是挺好的,打call;
本題利用了先序遍歷的“先根”性質(每輸出的一個值都是當先dfs時間戳的節點的值),且序列中的第一個元素一定是根節點;——性質1;
中序遍歷則利用了“左左右右”(左邊的是左兒子,右邊是右兒子);——性質2;
兩者相結合:
我們就可以用先序遍歷的根節點,去找這個根節點在中序遍歷的位置,那麼利用性質2,去找它的左兒子和右兒子的區間分別在哪裡,確定了左兒子和右兒子的區間後,這兩個區間內一定又會有一個“當爸爸的父親節點“,而這個區間裡面的父親節點,一定是先序遍歷中當前節點向後的一個節點(性質1)相當於二分;
下面是程式碼(st是start的縮寫,en是end的縮寫)
1、陣列(在遍歷的時候就輸出)
2、建樹,先建樹後常規跑後序 dfs;#include<bits/stdc++.h> using namespace std; string s1,s2; void wans( int st1 , int en1 , int st2 , int en2 ){ if( st1 <= en1 ){ int root = s2.find ( s1[st1] , st2 ); wans ( st1+1 , st1+root-st2 , st2 , root-1 ); wans ( st1+root-st2+1 , en1 , root+1 , en2 ); cout<<s1[st1]; } } int main(){ cin>>s1; cin>>s2; wans(0 , s1.size()-1 , 0 , s2.size()-1 ); return 0; }
感覺lqx和hy同學學得很快,加油!#include<bits/stdc++.h> using namespace std; typedef struct node; typedef node *tree; struct node{ char data; tree l,r; }; tree root; string s1,s2; void build( int st1 , int en1 , int st2 , int en2 , tree &bt ){ bt=new node; bt->data = s1[st1]; if( st1 <= en1 ){ int x = s2.find( s1[st1] , st2 ); build( st1+1 , st1+x-st2 , st2 , x-1 , bt->l); build( st1+x-st2+1 , en1 , x+1 , en2 , bt->r); } else bt = NULL; } void visit( tree bt ){ if( bt ){ visit( bt->l ); visit( bt->r ); cout<<bt -> data; } } int main(){ cin>>s1; cin>>s2; build( 0 , s1.size()-1 , 0 , s2.size()-1 , root ); visit(root); return 0; }