L2-011玩轉二叉樹(二叉樹重建及層序遍歷)
阿新 • • 發佈:2018-12-13
玩轉二叉樹(二叉樹的重建及層序遍歷)
題目:
給定一棵二叉樹的中序遍歷和前序遍歷,請你先將樹做個鏡面反轉,再輸出反轉後的層序遍歷的序列。所謂鏡面反轉,是指將所有非葉結點的左右孩子對換。這裡假設鍵值都是互不相等的正整數。
輸入格式:
輸入第一行給出一個正整數
N
(≤30),是二叉樹中結點的個數。第二行給出其中序遍歷序列。第三行給出其前序遍歷序列。數字間以空格分隔。
輸出格式:
在一行中輸出該樹反轉後的層序遍歷的序列。數字間以1個空格分隔,行首尾不得有多餘空格。
輸入樣例:
7 1 2 3 4 5 6 7 4 1 3 2 6 5 7
輸出樣例:
4 6 1 7 5 3 2
最近在資料結構課上學了二叉樹,但老師講的東西是很有限的,感覺自己對二叉樹的理解並不深刻。恰巧做到這個題。看到這個題是比較懵逼的,給定一棵二叉樹的前序遍歷和中序遍歷,要怎麼樣來重建這棵二叉樹呢?思考之後,我在紙上重建了樣例給的樹,但要用程式怎樣實現呢?思索了一下,但想法都是碎片化的,不能形成一條完整的思路(我太菜了而且在家做也時常靜不下心來)。於是看了二叉樹重建這個才明白。二叉樹重建用了分治的思想,分別處理該節點的左子樹和右子樹,並呼叫遞迴函式完成重建。
程式碼實現:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#define MAX 10100
using namespace std;
int Nodes[MAX];
int preNode[MAX];
int midNode[MAX];
int pos=0;
int N;
void rebuild(int L,int R,int n)
{
if(L>=R)
{
Nodes[n]=-1;
return;
}
int root=preNode[pos++];
Nodes[n]=root;
int m=find(midNode,midNode+ R,root)-midNode; //得到該節點在中序遍歷陣列的下標
rebuild(L,m,2*n+1); //重建左子樹
rebuild(m+1,R,2*n+2); //重建右子樹
}
void bfs()
{
int n=0;
queue<int> q;
q.push(n);
while(q.size())
{
int n=q.front();
int value=Nodes[n];
q.pop();
if(value!=-1)
{
if(n!=0)
cout<<" ";
cout<<value;
q.push(2*n+2);
q.push(2*n+1);
}
}
}
int main()
{
cin>>N;
for(int i=0;i<N;i++)
cin>>midNode[i];
for(int i=0;i<N;i++)
cin>>preNode[i];
rebuild(0,N,0);
bfs();
return 0;
}