两种构建方式的区别:
1.利用中序遍历和后序遍历构建二叉树,最先建立的是 右子树,接着是左子树,
后序遍历中根节点是最后一个元素
2.利用前序遍历和中序遍历构建二叉树,最先建立的是 左子树,接着才是右子树,
前序遍历中根节点在第一个元素
用递归来构建树,建立左右树的顺序不同,遍历数组的起始点,方向也不同。
1.利用中序遍历和后序遍历构建二叉树
在last[]中找到根节点,再在in[]中找到根节点的位置i,在in[i+1,end]中找右子女,在in[first,i-1]中找左子女,一直递归直到找到叶子结点为止...
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
struct node
{
int data;
node *l,*r;
node (){
l=NULL;
r=NULL;
}
};
int last[30];
int in[30];
int cnt;//后序遍历数组的位置
node *create(node *root,int first,int end) // 根据前序遍历和中序遍历递归创建树
{
root=new node(); //为暂时的根结点创建一个实例对象,默认左右子女为空
root->data=last[cnt--];//根节点的值等于后序遍历的最后一个值
int i;
for(i=first;i<=end;i++) //在中序遍历的数组中寻找根节点的位置
{
if(in[i]==root->data){//在中序遍历中找到结点就弹出
break;
}
}
if(i<end){ //如果根节点的右边还有数据,先构建右子树
root->r=create(root->r,i+1,end);
}
if(i>first){//如果根节点的左边还有数据,先构建左子树
root->l=create(root->l,first,i-1);
}
return root;
}
void sequence(node *root)//层次遍历
{
int num=0; //记录结点个数
if(!root){
return;
}
queue<node *>v;//存放左右结点的队列
v.push(root);//先把根结点放在队列中
num++;//结点个数+1
node *tmp; //临时结点
while(!v.empty()) //当队列中还存在未输出的结点
{
tmp=v.front();//得到第一个结点
v.pop();//弹出
if(num>1){ //从第二个结点开始,前面输出一个空格隔开(题目规定)
printf(" ");
}
printf("%d",tmp->data);
if(tmp->l){ //如果左子女存在,左子女进队列
v.push(tmp->l);
}
if(tmp->r){//如果右子女存在,右子女进队列
v.push(tmp->r);
}
num++;//结点个数加1
}
printf("\n"); //最后换行
}
int main()
{
int n;
scanf("%d",&n);//输入结点个数
int i;
for(i=0;i<n;i++) //输入后序遍历结果
{
scanf("%d",&last[i]);
}
for(i=0;i<n;i++)//输入中序遍历结果
{
scanf("%d",&in[i]);
}
cnt=n-1;
node *root=create(root,0,n-1);//用create创建树,并返回树的根节点
printf("利用后序和中序构建二叉树,层次遍历结果:\n");
sequence(root);//遍历输出
return 0;
}
输入输出实例,以及运行结果:
2.利用前序遍历和中序遍历构建二叉树,只需要改变上述代码cnt ,初始cnt=0,然后cnt++, 以及调整构建左右树的顺序 即可,想想然后自己码一下吧。