二叉樹訓練~樹的遍歷~解題報告

樹的遍歷

題目描述:

給定一棵二叉樹的後序遍歷和中序遍歷,請你輸出其層序遍歷的序列。
這裏假設鍵值都是互不相等的正整數。

Input:

輸入第一行給出一個正整數N(≤30),是二叉樹中結點的個數。
第二行給出其後序遍歷序列。第三行給出其中序遍歷序列。數字
間以空格分隔。

Output:

在一行中輸出該樹的層序遍歷的序列。數字間以1個空格分隔,
行首尾不得有多餘空格。

Sample Input:

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

Sample Output:

4 1 6 3 5 7 2

二叉樹遍歷:

這道題考的是二叉樹的遍歷問題,先講這道題思路前,先講一下二叉樹的
四種基礎遍歷:

 1. 前序遍歷:根節點->左子點->右子點,這個序列特點在於他的根
 永遠在第一位。
 2. 中序遍歷:左節點->根節點->右節點,這個序列特點在於只要找
 出根的位置,就能劃分左右子樹。
 3. 後序遍歷:左節點->右節點->根節點,這個序列特點在於他的根
 永遠在最後一位。
 4. 層序遍歷:這個遍歷是每一層從左到右開始遍歷,遍歷完第一層
 就到下一層,他的遍歷可以用隊列結構,因爲滿足先進後出的特點。

思路分析:

思路分析:這道題給出了後序與中序的遍歷順序以及節點數,這道題可以用
遞歸或者鏈表去寫,這裏先講遞歸的思路,遞歸的思路相當於:用DFS的方
式去找出左右子樹的節點,這裏需要判斷邊界和遞歸條件以及根的位置,那
麼我們知道了後序遍歷。

 1. 判斷邊界:只要遞歸的時候,他所遞歸的值不要超過後序與中序區間
 就可以了。
 2. 找根節點:這裏因爲有後序,那麼根一定在後序的最後一個點,按照
 這個條件遞歸就可以了。
 3. 遞歸條件:這裏具體看代碼註釋,結合代碼和註釋才容易理解

代碼:

#include<queue>
#include<cstdio>
#include<iostream>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
int b[40],a[40];//記錄後序與中序。 
map<int,int>R,L;//這個可以用二維數組代替,用map(映射)好理解一點 
//記錄左子樹和右子樹的節點,這裏強調一下
//R[root]這裏所記錄的點是根的右子點,不是在該點的值 
//[m,n]爲後序的區間,[d,f]爲前序的區間 
int LemonCreatTree(int m,int n,int d,int f)
{
	int i;
	if(m>n)//越界判斷。這裏可以換成d>f也是正確的,只要判斷2個其中一個序列是否越界就行 
	{
		return 0;
	}
	int root=b[n];//得到根節點 
	int p=0,num;
	for(num=d;num<=f;num++)//在中序中,找到與根相同的點,記錄下標 
	{
		if(a[num]!=root)
		{
			p++;//記錄後序中與根相差多少 
		}
		else
		break;
	}
	//這裏可以講一下規律,後序的遍歷方式是左右根,所以根肯定是在最後面
	//在中序來判斷左右子樹,然後p記錄其所出現的位置
	//這裏2個遞歸比較難搞的是後序,中序只需要找num值就可以了,因爲num爲中序所出現的位置
	//那麼num右邊的爲右子樹,邊界設爲f,那麼num-1左邊的爲左子樹,邊界設爲m就行 
	// 例如:1 2 3   4   5 6 7,p記錄爲4,右邊爲右子樹的所有點,左邊爲左子樹的所有點
	// 那麼R[root]的區間可以判斷爲m+p,那麼找L[root]可以從m+p-1開始找其右子樹,其邊界
	//爲m初始點,因爲其後序尋找是從後到前的,所以很好理解  
	R[root]=LemonCreatTree(m+p,n-1,num+1,f);//創建左子樹 
	L[root]=LemonCreatTree(m,m+p-1,d,num-1);//創建右子樹 
	return root;//返回根節點 
}
void LemonBFS(int root)//輸出層序遍歷 
{
	queue<int>q;
	q.push(root);
	int cnt=0;
	while(!q.empty())
	{
		int n=q.front();
		q.pop();
		printf(cnt++==0?"%d":" %d",n);//輸出格式問題 
		if(L[n])
		{
			q.push(L[n]);
		}
		if(R[n])
		{
			q.push(R[n]);
		}
	}
}

int main()
{
	int d;
	scanf("%d",&d);//輸入節點 
	for(int i=1;i<=d;i++)//輸入得到後序 
	{
		scanf("%d",&b[i]);
	}
	for(int i=1;i<=d;i++)//輸入得到中序 
	{
		scanf("%d",&a[i]);
	}
	int root=LemonCreatTree(1,d,1,d);//獲得左右子樹節點 
	LemonBFS(root);//層序遍歷直接用BFS加隊列就好了 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章