GPLT L2-006 树的遍历(二叉树)
题意:
给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。
思路:
后序遍历序列 = 左子树遍历序列 + 右子树遍历序列 + 根节点。
中序遍历序列 = 左子树遍历序列 + 根节点 + 右子树遍历序列。
找到根节点,再利用根节点计算新的后、中遍历序列端点。
Tips:
注意建树时传根节点的引用。
#include <bits/stdc++.h> using namespace std; const int M=35; int n,a[M],b[M];//a数组储存后序遍历,b数组储存中序遍历 map<int,int> posb;//后序遍历中某点在中序遍历中的位置 struct Bt{//二叉树结点 int v; Bt *l,*r; }*root; void build_tree(Bt* & rt,int l1,int r1,int l2,int r2){//l1~r1为该树的后序遍历序列区间,l2~r2为中序遍历序列区间。 if(l1>r1||l2>r2){//若不存在有效遍历 rt=nullptr; return; } rt=new(Bt); rt->v=a[r1];//后序倒数第一个即为该子树的根节点 int mid=posb[a[r1]];//该端点在中序遍历中的位置 int len=mid-l2;//左子树的长度 build_tree(rt->l,l1,l1+len-1,l2,mid-1);//递归建立左子树 build_tree(rt->r,l1+len,r1-1,mid+1,r2);//递归建立右子树 } void Print_level(Bt* t){ queue<Bt*> q; cout<<(t->v); if(t->l!=nullptr) q.push(t->l); if(t->r!=nullptr) q.push(t->r); while(!q.empty()){ Bt* t=q.front(); q.pop(); if(t!=nullptr){ cout<<' '<<(t->v); if(t->l!=nullptr) q.push(t->l); if(t->r!=nullptr) q.push(t->r); } } } int main(){ cin>>n; for(int i=0;i<n;i++) cin>>a[i]; for(int i=0;i<n;i++){ cin>>b[i]; posb[b[i]]=i; } build_tree(root,0,n-1,0,n-1); Print_level(root); return 0; }
最初的做法:
#include <bits/stdc++.h> using namespace std; const int M=35; struct Bt{ int v; Bt *l,*r; }; int n,a[M],b[M];//a数组储存后序遍历,b数组储存中序遍历 map<int,int> posa,posb;//某值在后序、中序遍历中的位置 Bt *root; void build_node(Bt* & pre,int last,int l,int r){//last为根节点的位置,l~r为中序遍历的左右端点 pre=new(Bt); pre->v=a[last]; int mid=posb[a[last]];//查找在中序遍历的位置 int last1=-1,last2=-1; int l1=l,r1=mid-1;//计算根节点两边区间的端点 int l2=mid+1,r2=r; for(int i=l1;i<=r1;i++)//枚举该子树结点在后序遍历中的位置,最大值即为该子树根节点的位置 last1=max(last1,posa[b[i]]); for(int i=l2;i<=r2;i++) last2=max(last2,posa[b[i]]); if(l1<=r1)//如果中序遍历区间有效,继续建立子树结点 build_node(pre->l,last1,l1,r1); else pre->l=nullptr; if(l2<=r2) build_node(pre->r,last2,l2,r2); else pre->r=nullptr; } void Print_level(Bt* t){ queue<Bt*> q; cout<<(t->v); if(t->l!=nullptr) q.push(t->l); if(t->r!=nullptr) q.push(t->r); while(!q.empty()){ Bt* t=q.front(); q.pop(); if(t!=nullptr){ cout<<' '<<(t->v); if(t->l!=nullptr) q.push(t->l); if(t->r!=nullptr) q.push(t->r); } } } int main() { cin>>n; for(int i=0;i<n;i++){ cin>>a[i]; posa[a[i]]=i; } for(int i=0;i<n;i++){ cin>>b[i]; posb[b[i]]=i; } build_node(root,n-1,0,n-1); Print_level(root); return 0; }