題目:
一個二叉樹,如果每一個層的結點數都達到最大值,則這個二叉樹就是完美二叉樹。對於深度為 D 的,有 N 個結點的二叉樹,若其結點對應於相同深度完美二叉樹的層序遍歷的前 N 個結點,這樣的樹就是完全二叉樹。
給定一棵完全二叉樹的後序遍歷,請你給出這棵樹的層序遍歷結果。
輸入格式:
輸入在第一行中給出正整數 N(≤30),即樹中結點個數。第二行給出後序遍歷序列,為 N 個不超過 100 的正整數。同一行中所有數字都以空格分隔。
輸出格式:
在一行中輸出該樹的層序遍歷序列。所有數字都以 1 個空格分隔,行首尾不得有多餘空格。
輸入樣例:
8
91 71 2 34 10 15 55 18
輸出樣例:
18 34 55 71 2 10 15 91
題目就是講述了什麼是完全二叉樹:完美二叉樹就是滿二叉樹。完全二叉樹:只有倒數第一層和倒數第二層的結點的度數可以小於2,並且倒數第一層上的結點都集中在該層最左邊的若干位置上,則此二叉樹稱為完全二叉樹。
懂了什麼是完全二叉樹,接下來就是模擬二叉樹的後序遍歷(假設A,B是完全二叉樹,題目給了A樹的後序遍歷序列(只知道序列,不能直觀的知道對應節點編號的資料),B先看成是空樹,然後用B樹去模擬後序遍歷過程,在過程中填入A樹的後序遍歷序列資料,A樹的形狀以及對應節點編號的資料就在B樹上得到了還原,還原的B樹按節點編號從1到n輸出資料就是層序遍歷的結果)。想的時候用樹形去想,做 我是用陣列表示B樹,根節點編號為1,遞迴模擬後序遍歷。
不懂再看這裡:如果二叉數節點編號從1~n編號,層序遍歷訪問到的編號就是從1~n。用陣列模擬後序遍歷序列,就是模擬節點編號的訪問次序。那我用題目給的後序遍歷資料依次對應模擬的訪問編號,就可以還原這棵n個節點的完全二叉樹上每個節點編號對應的資料(僅限完全二叉樹:並且倒數第一層上的結點都集中在該層最左邊的若干位置上,則此二叉樹稱為完全二叉樹)。
程式碼:
#include<bits/stdc++.h> using namespace std; #define ll long long const int N = 30+5; #define inf 0x3f3f3f3f #define mod 998244353 #define pre(a,b,c) for(int a=b;a<c;a++) #define pres(a,b,c) for(int a=b;a<=c;a++) int r; int tree[N]; int n; void FF(int id,int *a) { if(id > n) return; FF(id<<1,a); FF(id<<1|1,a); tree[id] = a[++r]; } int main() { cin>>n; int a[N]; for(int i = 1;i <= n;i++) { cin>>a[i]; } FF(1,a); for(int i = 1;i <= n;i++) { cout<<tree[i]; if(i!=n) cout<<' '; } }