Description
給出一棵二叉樹的中序遍歷和每個節點的父節點,求這棵二叉樹的先序和後 序遍歷。
Input
輸入第一行為一個正整數 n 表示二叉樹的節點數目, 節點編號從 1 到 n,其中 1 為根節點。
第 2 行有 n 個數字, 第 i 個數字表示 i 的父親節點。( 1 的父親節點為 0, 表示無)
第 3 行為中序遍歷。
30%的資料: n<=20;
60%的資料: n<=1000;
100%的資料: n<=10000;
Output
輸出 2 行, 第一行為先序遍歷,第二行為後序遍歷。
Sample Input
10
0 7 2 2 9 1 8 1 6 8
9 5 6 1 10 8 7 3 2 4
Sample Output
1 6 9 5 8 10 7 2 3 4
5 9 6 10 3 4 2 7 8 1
思路
存下每個節點的左右兒子,然後根據中序遍歷判斷誰是左兒子,誰是右兒子,建完樹,跑一下先序遍歷和後序遍歷
#include<iostream>
using namespace std;
const int N = 10010;
int lson[N], rson[N];//存結點x的左右兒子
int last[N];
void PreOrder(int x)
{
//題目給定1為根
if (x != 1) cout << " ";
cout << x;
if (lson[x]) PreOrder(lson[x]);
if (rson[x])PreOrder(rson[x]);
}
bool flag = true;
void PostOrder(int x)
{
if (lson[x]) PostOrder(lson[x]);
if (rson[x])PostOrder(rson[x]);
if (flag) cout << x;
else cout<<" " << x;
flag = false;
}
int main() {
int n;
cin >> n;
int tmp;
//先預設存左,左存了就存右
for (int i = 1; i <= n; i++)
{
cin >> tmp;
if (!tmp)continue;
if (!lson[tmp]) lson[tmp] = i;
else rson[tmp] = i;
}
//last存tmp出現的先後,i表示先後
for (int i = 1; i <= n; i++)
{
cin >> tmp;
last[tmp] = i;
}
for (int i = 1; i <= n; i++)
{
if (lson[i] && rson[i])
{
//左根右
if (last[rson[i]] < last[lson[i]])
{
swap(lson[i], rson[i]);
}
}
//左根右 如果rson[i](只是個值)在根前, 那就是右兒子
else if (!lson[i] && rson[i])
{
if (last[rson[i]] < last[i])
{
lson[i] = rson[i];
rson[i] = 0;
}
}
else if (lson[i] && !rson[i])
{
if (last[lson[i]] > last[i])
{
rson[i] = lson[i];
lson[i] = 0;
}
}
}
PreOrder(1); cout << endl;
PostOrder(1); cout << endl;
}