树的遍历
给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数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
法一:
#include<bits/stdc++.h>
using namespace std;
int post[5000],in[5000],pos;
struct node{
int v,l,r;
}T[20005];
void dfs(int inL,int inR,int n){
if(inL>=inR)return;
T[n].v=post[pos--];//后序遍历最末尾为根结点
T[n].l=2*n,T[n].r=2*n+1;//存的都是下标
int k; //更结点
for(k=inL;k<inR;k++){
if(in[k]==T[n].v)break;
}
dfs(k+1,inR,2*n+1);//必须先重建右子树
dfs(inL,k,2*n);
}
int dex=1;
void bfs(){
queue<int> q;
q.push(1);
while(!q.empty()){
node cur=T[q.front()];
q.pop();//删除当前队列最前面的
if(dex++==1)cout<<cur.v;
else cout<<" "<<cur.v;
if(T[cur.l].v!=-1)q.push(cur.l);
if(T[cur.r].v!=-1)q.push(cur.r);
}
}
int main(){
int n;cin>>n;
for(int i=0;i<n;i++)cin>>post[i];
for(int i=0;i<n;i++)cin>>in[i];
memset(T,-1,sizeof(T));//结构体置-1,当它为负一是表示已经到了最末尾
pos=n-1;
dfs(0,n,1);
bfs();
return 0;
}
法二:
#include<bits/stdc++.h>
using namespace std;
struct node{
int data,l,r;
}e[10005];
int in[50],lst[50];
int no=0;
int dfs(int inL,int inR,int lstL,int lstR){
if(lstL>lstR)return -1;
int last=no;
e[no++].data=lst[lstR];
int k;
for(k=inL;k<=inR;k++){
if(in[k]==lst[lstR])break;
}
int len=k-inL;
e[last].l=dfs(inL,k-1,lstL,lstL+len-1);
//cout<<e[last].data<<" ";
e[last].r=dfs(k+1,inR,lstL+len,lstR-1);
return last;
}
int dex=1;
void bfs(){
queue<int> q;
q.push(0);
while(!q.empty()){
node cur=e[q.front()];
q.pop();
if(dex++==1)cout<<cur.data;
else cout<<" "<<cur.data;
if(cur.l!=-1)q.push(cur.l);
if(cur.r!=-1)q.push(cur.r);
}
}
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++)cin>>lst[i];
for(int i=0;i<n;i++)cin>>in[i];
memset(e,-1,sizeof(e));
dfs(0,n-1,0,n-1);
bfs();
return 0;
}
这里我们假设题目是:给定一棵二叉树的后序遍历和中序遍历,请你输出其前序遍历的序列。
当然了这个直接还是用这个代码,只不过要多加一行而已;
看代码:
#include<bits/stdc++.h>
using namespace std;
struct node{
int data,l,r;
}e[10005];
int in[50],lst[50];
int no=0;
int dfs(int inL,int inR,int lstL,int lstR){
if(lstL>lstR)return -1;
int last=no;
e[no++].data=lst[lstR];
int k;
for(k=inL;k<=inR;k++){
if(in[k]==lst[lstR])break;
}
int len=k-inL;
cout<<e[last].data<<" ";//前序就是先根在左右。就是这么简单,你不信可以直接将这行代码放在l和r的中间看一下输出的是不是中序遍历。
e[last].l=dfs(inL,k-1,lstL,lstL+len-1);
e[last].r=dfs(k+1,inR,lstL+len,lstR-1);
return last;
}
int dex=1;
void bfs(){
queue<int> q;
q.push(0);
while(!q.empty()){
node cur=e[q.front()];
q.pop();
if(dex++==1)cout<<cur.data;
else cout<<" "<<cur.data;
if(cur.l!=-1)q.push(cur.l);
if(cur.r!=-1)q.push(cur.r);
}
}
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++)cin>>lst[i];
for(int i=0;i<n;i++)cin>>in[i];
memset(e,-1,sizeof(e));
dfs(0,n-1,0,n-1);
bfs();
return 0;
}
玩转二叉树
给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数N
(≤30),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行给出其前序遍历序列。数字间以空格分隔。
输出格式:
在一行中输出该树反转后的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。
#include<bits/stdc++.h>
using namespace std;
int pre[50],in[50];
struct node{
int v,l,r;
}T[20005];
int no=0;
int dfs(int inL,int inR,int preL,int preR){
if(preL>preR) return -1;
int last=no;
T[no++].v=pre[preL];
int k;
for(k=inL;k<=inR;k++){
if(in[k]==pre[preL])break;
}
int len=k-inL;
T[last].l=dfs(inL,k-1,preL+1,preL+1+len-1);
T[last].r=dfs(k+1,inR,preL+len+1,preR);
return last;
}
int dex=1;
void bfs(){
queue<int>q;
q.push(0);
while(!q.empty()){
node cur=T[q.front()];
q.pop();
if(dex++==1)cout<<cur.v;
else cout<<" "<<cur.v;
if(cur.r!=-1)q.push(cur.r);
if(cur.l!=-1)q.push(cur.l);
}
}
int main(){
int N;cin>>N;
for(int i=0;i<N;i++)cin>>in[i];
for(int i=0;i<N;i++)cin>>pre[i];
memset(T,-1,sizeof(T));
dfs(0,N-1,0,N-1);
bfs();
return 0;
}