题目要求:输入二叉树前序遍历和中序遍历的结果,假设输入的数字都不包含重复数字,构建出满足序列的二叉树。
树结构是我一直很头疼的一部分,感觉他是数据结构中最繁琐的了,如果我们要想学会这部分首先大家一定要明白树的结构,以及前序遍历,中序遍历,后续遍历的特点,还有就是脑子中有递归的概念。明白看这些特点我们再学树就如鱼得水了,废话不多说,大家可以看看代码,我把需要注意的地方都用注释写了下来,可能比较简陋,有问题请大家指正。
#include <iostream>
#include<vld.h>
using namespace std;
struct Btnode
{
int data;
Btnode *left;
Btnode* right;
};
Btnode* Constructnode(int *startpre,int *endpre,int *startin,int* endin);//函数声明
Btnode* construct(int *pre,int *in,int length)
{
if(pre==NULL || in==NULL || length<0)//判断形参的合法性
{
return NULL;
}
return Constructnode(pre,pre+length-1,in,in+length-1);//构建二叉树结构
}
Btnode* Constructnode(int *startpre,int *endpre,int *startin,int* endin)//形参为前序序列和中序序列的开头和结尾
{
Btnode* root=new Btnode;//创建根节点
int rootdata=startpre[0];//前序遍历的顺序为根左右,所有第一个数字为根
root->data=rootdata;
root->left=NULL;
root->right=NULL;
if(startpre==endpre)// 只有一个根节点,没有左右孩子的情况
{
if(startin==endin && *startpre==*startin)
{
return root;
}
else//说明前序序列的输入有问题
{
throw std::exception("输入的序列有误\n");
}
}
int *rootin=startin;
while(rootin<=endin&&*rootin!=rootdata)//找出中序遍历根的所在位置
rootin++;//rootin保存根节点在中序遍历里面的位置
if(*rootin!=rootdata)//如果在中序遍历中没有找到说明中序序列输入的序列有问题。
{
throw exception("输入的序列有误\n");
}
int leftnum=rootin-startin;//算出根节点的左孩子个数
if(leftnum>0)//大于零说明有左孩子,所以要创建左孩子节点
{
root->left= Constructnode(startpre+1,startpre+leftnum,startin,rootin-1);//利用递归将规模缩小,将那些左孩子视为一个二叉树,然后前序序列中的第二个数字作为新的根节点,传入三个左孩子,中序序列则传入前三个节点。
}
if(leftnum<endpre-startpre)//因为输入的序列长度=左孩子个数+右孩子个数,所以如果左孩子的个数小于序列的长度就说明存在右孩子。
{
root->right= Constructnode(startpre+leftnum+1,endpre,rootin+1,endin);//递归缩小规模,前序遍历数组传入后四个右孩子节点,中序遍历数组传入后四个有孩子节点
}
return root;
}
void remove(Btnode *root)//防止内存泄漏
{
if(root==NULL)
{
return;
}
remove(root->left);
remove(root->right);
delete[] root;
}
int main()
{
int n;
printf("请输入二叉树的叶子数\n");
scanf("%d",&n);
int *pre=new int[n]();
int *in=new int[n]();
printf("请输入前序遍历的数字\n");
for(int i=0;i<n;i++)
{
scanf("%d",&pre[i]);
}
printf("请输入中序遍历的数字\n");
for(int j=0;j<n;j++)
{
scanf("%d",&in[j]);
}
Btnode *root=construct(pre,in,n);//创建完毕,查看root的左右孩子就可以看到二叉树的结构
remove(root);//最后别忘记内存泄漏哟
delete[] pre;
delete[] in;
}