天天看點

二叉樹的先序/中序/後序周遊,以及根據中序+先序/後序 周遊推導整個樹

二叉樹周遊:

先序周遊:根左右

中序周遊:左根右

後序周遊:左右根

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
int le[55],ri[55];//前序 中序
int lef[55],rig[55];//中序 後序
int pre[55],in[55],la[55];//前序 中序 後序
int ans[55];
int p,post;
int dfs(int l,int r){
  if(l>r) return -1;
  int t=pre[p];
  p++;
  int cnt=0;
  for(int i=l;i<=r;i++){
    if(t==in[i]){
      cnt=i;
      break;
    }
  }
  le[t]=dfs(l,cnt-1);
  ri[t]=dfs(cnt+1,r);
  return t; 
}
 
int dfs1(int l,int r){
  if(l>r) return -1;
  int t=la[post];
  post--;
  int cnt=0;
  for(int i=l;i<=r;i++){
    if(t==in[i]){
      cnt=i;
      break;
    }
  }
  rig[t]=dfs1(cnt+1,r);
  lef[t]=dfs1(l,cnt-1);
  return t;
}
int main(){
  int n;
  cin>>n;
  for(int i=0;i<n;i++) cin>>pre[i];//先序 
  for(int i=0;i<n;i++) cin>>in[i];//中序 
  for(int i=0;i<n;i++) cin>>la[i];//後序 
  p=0;post=n-1;
  int cnt=0;
  //前序 中序
  int root=dfs(0,n-1);
  queue<int> q;
  q.push(root);
  while(!q.empty()){
    int u=q.front();q.pop();
    if(u==-1) continue;
    ans[cnt++]=u;
    q.push(le[u]);
    q.push(ri[u]); 
  }
  cout<<ans[0];
  for(int i=1;i<cnt;i++) cout<<" "<<ans[i];
  cout<<endl;
  
  //中序 後序
  cnt=0;
  root=dfs1(0,n-1);
  q.push(root);
  while(!q.empty()){
    int u=q.front();q.pop();
    if(u==-1) continue;
    ans[cnt++]=u;
    q.push(lef[u]);
    q.push(rig[u]); 
  }
  cout<<ans[0];
  for(int i=1;i<cnt;i++) cout<<" "<<ans[i];
  cout<<endl;
  return 0; 
}
/*
8
1 2 4 5 3 6 7 8
4 2 5 1 6 3 7 8
4 5 2 6 8 7 3 1
11
1 2 4 8 5 9 3 6 10 11 7
4 8 2 5 9 1 10 6 11 3 7
8 4 9 5 2 10 11 6 7 3 1 
*/