【天梯賽】L2-006. 樹的遍歷(層次遍歷)
阿新 • • 發佈:2018-12-24
題目描述:
給定一棵二叉樹的後序遍歷和中序遍歷,請你輸出其層序遍歷的序列。這裡假設鍵值都是互不相等的正整數。
輸入格式:
輸入第一行給出一個正整數N(<=30),是二叉樹中結點的個數。第二行給出其後序遍歷序列。第三行給出其中序遍歷序列。數字間以空格分隔。
輸出格式:
在一行中輸出該樹的層序遍歷的序列。數字間以1個空格分隔,行首尾不得有多餘空格。
輸入樣例:7 2 3 1 5 7 6 4 1 2 3 4 5 6 7輸出樣例:
4 1 6 3 5 7 2
題目思路:
如果題目說,給出後序遍歷和中序遍歷,求先序遍歷,那麼你一定會做(如果不會做,可以先學會如何通過中序+後序,求先序,然後再來學習本題)。現在題目的前提條件不變,但是求的是層次遍歷。當然你可以通過後序和中序建樹,然後用BFS輸出層次遍歷的結果。這裡我採用的是在遞迴函式中新增一個引數index來表示當前遞迴層次中根節點應該在樹中的座標(層次遍歷的座標)。
題目中給出的資料的二叉樹如圖所示。
遞迴的過程如圖所示:
我們可以看出每次遞迴左子樹的時候,左子樹的根節點在層次遍歷中的座標是2*index+1,(我們假設左子樹根節點的父親結點的座標是index。如:圖中權值為1的結點和權值為4的結點的關係)。同理右子樹在層次遍歷中的座標是2*index+2。因此我們可以新開闢一個數組在遞迴的過程中,每個結點在層次遍歷中的位置,最後輸出該陣列即可。需要注意的是,如果二叉樹的結點有n個,那麼最多有n層,最少有log2(n+1)層,因此陣列最大需要開2^30-1個。如果給定7個結點,那麼他最多有七層,顯示,我們在輸出心宣告的陣列的時候,不能只輸出前7個的值,因為最後一個結點的座標是2^7-2。
題目程式碼:
#include<cstdio> #include<cstring> #include<iostream> #define MAXN 10000 using namespace std; int s1[MAXN], s2[MAXN], s3[MAXN]; int n; /* p1 p2 q1 a2 表示兩種遍歷結果的起始位置 index表示當前根節點在二叉樹中的位置(層次遍歷) */ void f(int p1, int p2, int q1, int q2, int index) { if(p1>p2 || q1>q2) return ; int i = p1 ; while(s1[i] != s2[q2]) i++; s3[index] = s1[i]; //left f(p1, i-1, q1, q1+i-1-p1, 2*index+1); //right f(i+1, p2, q1+i-p1, q2-1, 2*index+2); } int main() { cin>>n; for(int i=0; i<n; i++) cin>>s2[i]; for(int i=0; i<n; i++) cin>>s1[i]; memset(s3,0,sizeof(s3)); f(0, n-1, 0, n-1, 0); //cnt用來記錄有效數字的個數 int cnt = 0; for(int i=0; i<=100000; i++) { if(cnt==n)break; if(s3[i]){ cnt++; if(i)cout<<" "; cout<<s3[i]; } } return 0; }