資料結構——根據兩種遍歷方式推得另外一種遍歷方式
阿新 • • 發佈:2018-11-21
首先說一下,只有 先序+中序——>後序,以及後序+中序——>前序,這兩種推舉方式,因為當只給出前序以及後序的遍歷方式時,推得的中序是不唯一的,也就是不存在。
方法(核心):是根據每種遍歷方式的特點,以前序遍歷和後序遍歷為基準,對中序遍歷進行割裂(這裡姑且稱它為割裂法)。
這個要求我們對三種遍歷方式 爛熟於心(必須透徹瞭解!!!)才能推得建樹方式。這裡給出兩篇講的很不錯的部落格 三種遍歷方式詳解、知二推三的粗略程式碼。
由於先序遍歷的便捷性,中序遍歷前序遍歷推得後續遍歷是比較容易的,所以這裡只給出中+後——>前的程式碼。
一定要牢記上面所說的割裂方法,瞭解此方法後,這些程式碼是不必要記住的。
下面的程式碼同時對應了PTA的一道題目,這裡給出題目以及AC程式碼;
7-1 根據後序和中序遍歷輸出先序遍歷 (25 分)
本題要求根據給定的一棵二叉樹的後序遍歷和中序遍歷結果,輸出該樹的先序遍歷結果。
輸入格式:
第一行給出正整數N(≤30),是樹中結點的個數。隨後兩行,每行給出N個整數,分別對應後序遍歷和中序遍歷結果,數字間以空格分隔。題目保證輸入正確對應一棵二叉樹。
輸出格式:
在一行中輸出Preorder:
以及該樹的先序遍歷結果。數字間有1個空格,行末不得有多餘空格。
輸入樣例:
7 2 3 1 5 7 6 4 1 2 3 4 5 6 7
輸出樣例:
Preorder: 4 1 3 2 6 5 7
AC程式碼(割裂法):
#include <bits/stdc++.h> using namespace std; const int maxn=1e5+10; int last[maxn],mid[maxn]; typedef struct node { int data; node* left; node* right; }*BiTree; node* solve(int *last,int *mid,int len) { if(len==0) return NULL; int pos=0; for(int i=0;i<len;i++) { if(mid[i]==last[len-1]) { pos=i; break; } } BiTree nodes=new node(); nodes->data=mid[pos]; //構建左子樹 nodes->left=solve(last,mid,pos); //構建右子樹 nodes->right=solve(last+pos,mid+pos+1,len-pos-1); return nodes; } void Preorder(BiTree tree)//先序遍歷 { if(tree==NULL) return; printf(" %d",tree->data); Preorder(tree->left); Preorder(tree->right); } int main() { int n; cin>>n; for(int i=0;i<n;i++) cin>>last[i]; for(int i=0;i<n;i++) cin>>mid[i]; BiTree tree=solve(last,mid,n); cout<<"Preorder:"; Preorder(tree); return 0; }