題目描述
給出一棵二叉樹的中序與後序排列。求出它的先序排列。(約定樹結點用不同的大寫字母表示,長度≤8 \le 8≤8)。
輸入格式
222行,均爲大寫字母組成的字符串,表示一棵二叉樹的中序與後序排列。
輸出格式
111行,表示一棵二叉樹的先序。
輸入輸出樣例
輸入 #1
BADC
BDCA
輸出 #1
ABCD
思路
給定二叉樹的中序遍歷和後序遍歷,以此來重建這棵二叉樹,重建完後進行一次先序遍歷就ok了
中序遍歷(左-根-右)是用來確定左子樹和右子樹的節點個數,先序遍歷和後序遍歷來確定根節點, 因爲先序遍歷的特性是(根-左-右),因此第一個結點必定是根節點;後序遍歷的特性是(左-右-根)因此最後一個節點必定是根節點。用以上方法來重建這棵二叉樹。最後進行一次先序遍歷。
PS:今天終於發現了這個代碼的錯誤之處,每次這個代碼結果都是對的,但全是WA,之前我一口咬定是評測系統的問題 ,但是經過好幾個oj都是錯的,逐漸讓我意識到事情的嚴重性 。。。今天把中序遍歷和後序遍歷輸入時的字符串改爲cin輸入就AC了,之前用的getline,能出結果而且結果都是對的,但就是全WA,不知道什麼原因。。。。
代碼
#include <iostream>
#include <algorithm>
#include <string>
#include <queue>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
struct node{ //結構體:數據,左孩子,右孩子
char data;
node* left;
node* right;
};
string zhong,hou,ans; //中序後序輸入
char post[10],mid[10]; //後續,中序
node *create(int zz,int zy,int hz,int hy) //(中序遍歷最左邊,中右,後左,後右 )
{
if(hz>hy) //如果後序遍歷的長度<=0,那麼二叉樹就不存在,返回NULL
return NULL;
node* root = new node; //新建一個結點,存放根節點
root->data = post[hy]; /*後序遍歷最後一個數是根節點
(後順序:左-右-根) */
int k;
for(k=zz;k<=zy;k++) //找中序遍歷的根節點位置
{
if(mid[k]==post[hy]) //找到就退出,k爲中序遍歷的根節點位置
break;
}
int numleft=k-zz; /*中序遍歷左邊爲左樹,右邊爲右樹 (中順序:左-根-右)
由此計算出左邊樹的結點數(k-1-zz+1 == k-zz) */
root->left = create(zz,k-1,hz,hz+numleft-1); //創建左樹
//將左子樹根節點位置返回給root左指針
root->right = create(k+1,hy,hz+numleft,hy-1); //創建右樹
//將右子樹根節點位置返回給root右指針
return root; //返回根節點
}
void xian(node *root) //先序遍歷(順序:根-左-右)
{
if(root == NULL) //結點不存在就返回
return;
cout<<root->data; //直接輸出根的data
xian(root->left); //走左孩子
xian(root->right); //右孩子
}
int main()
{
cin>>zhong>>hou; /*別用getline,不知道爲啥,但是
被狠狠的教訓過,結果是對的,但是各種WA*/
for(int i=0;i<zhong.size();i++)
mid[i]=zhong[i]; //將字符串放到數組中
for(int i=0;i<hou.size();i++)
post[i]=hou[i];
int len=zhong.size();
node* root = create(0,len-1,0,len-1);
//用root接受返回值, create(中左,中右,後左,後右)
xian(root);
//最後走一個先序遍歷
return 0;
}