主要我觉得可以分为三大板块,写三个函数就可以搞定这个问题,所以说这个不难,但对于初学者来说,一定要克服心里的障碍,不要害怕,嘿嘿,因为这也是我之前的真实想法。
定义树结构体
struct node{ //定义结构体建立树节点
int data;
node* lchild;
node* rchild;
};
int pre[maxn],in[maxn],post[maxn]; //存放先序,中序,后续的数组
先序和中序建立树
node* creaprein(int prel,int prer,int inl,int inr) //先序和中序建立树
{
if(prel>prer) return NULL; //递归边界,长度小于等于0,直接返回
node* root=new node; //建立新节点,存放根节点
root->data=pre[prel]; //根节点的数据域是根节点的值
int i;
for(i=inl;i<=inr;i++)
{
if(in[i]==pre[prel]) //找到该节点,并记录下标值
break;
}
int num=i-inl;
root->lchild=creaprein(prel+1,prel+num,inl,i-1); //递归其左子树
root->rchild=creaprein(prel+num+1,prer,i+1,inr); //递归其右子树
return root; //递归终点,返回根节点
}
中序和后序建立树
node* creainpost(int postl,int postr,int inl,int inr) //中序和后序建立树
{
if(postl>postr) return NULL; //递归边界
node* root=new node;
root->data=post[postr]; //先序和后序不同的就在于这里
int i;
for(i=inl;i<=inr;i++)
{
if(in[i]==post[postr])
break;
}
int num=i-inl;
root->lchild=creainpost(postl,postl+num-1,inl,i-1);//递归其左子树
root->rchild=creainpost(postl+num,postr-1,i+1,inr);//递归其右子树
return root;
}
层序输出
void prin(node* root) //层序遍历输出
{
queue<node*> q; //建立队列,并且这是node型指针
q.push(root); //压入根节点
while(!q.empty()) //判断队列是否为空,从而结束循环
{
node* now=new node;
now=q.front(); //建立新节点并且取出队列首元素,取出不是删除,类似一个把队首元素赋值的意思
cout<<now->data<<' '; //输出队首元素的值
q.pop(); //输出完之后就可以pop掉队首元素
if(now->lchild!=NULL) //但是此时的now依旧存在 判断他是否有左孩子
q.push(now->lchild); //递归左孩子
if(now->rchild!=NULL)
q.push(now->rchild); //递归右孩子
}
}
最后代码(中序和后序写的)
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include<algorithm>
#include<string>
#include<stdio.h>
#include<utility>
#include<sstream>
#include<queue>
using namespace std;
struct node{ //定义结构体建立树节点
int data;
node* lchild;
node* rchild;
};
int pre[maxn],in[maxn],post[maxn]; //存放先序,中序,后续的数组
node* creaprein(int prel,int prer,int inl,int inr) //先序和中序建立树
{
if(prel>prer) return NULL; //递归边界,长度小于等于0,直接返回
node* root=new node; //建立新节点,存放根节点
root->data=pre[prel]; //根节点的数据域是根节点的值
int i;
for(i=inl;i<=inr;i++)
{
if(in[i]==pre[prel]) //找到该节点,并记录下标值
break;
}
int num=i-inl;
root->lchild=creaprein(prel+1,prel+num,inl,i-1); //递归其左子树
root->rchild=creaprein(prel+num+1,prer,i+1,inr); //递归其右子树
return root; //递归终点,返回根节点
}
node* creainpost(int postl,int postr,int inl,int inr) //中序和后序建立树
{
if(postl>postr) return NULL; //递归边界
node* root=new node;
root->data=post[postr]; //先序和后序不同的就在于这里
int i;
for(i=inl;i<=inr;i++)
{
if(in[i]==post[postr])
break;
}
int num=i-inl;
root->lchild=creainpost(postl,postl+num-1,inl,i-1);//递归其左子树
root->rchild=creainpost(postl+num,postr-1,i+1,inr);//递归其右子树
return root;
}
void prin(node* root) //层序遍历输出
{
queue<node*> q; //建立队列,并且这是node型指针
q.push(root); //压入根节点
while(!q.empty()) //判断队列是否为空,从而结束循环
{
node* now=new node;
now=q.front(); //建立新节点并且取出队列首元素,取出不是删除,类似一个把队首元素赋值的意思
cout<<now->data<<' '; //输出队首元素的值
q.pop(); //输出完之后就可以pop掉队首元素
if(now->lchild!=NULL) //但是此时的now依旧存在 判断他是否有左孩子
q.push(now->lchild); //递归左孩子
if(now->rchild!=NULL)
q.push(now->rchild); //递归右孩子
}
}
int main()
{
int n; //树的节点个数
cin>>n;
for(int i=0;i<n;i++) //输入中序遍历
cin>>in[i];
for(int i=0;i<n;i++)
cin>>post[i]; //输入后序遍历
node* root=creainpost(0,n-1,0,n-1); //利用函数返回根节点
prin(root); //打印层序序列
return 0;
}
你们可以尝试自己写一下先序和中序建立树