剑指offer面试题:重建二叉树(注释很多)

       题目要求:输入二叉树前序遍历和中序遍历的结果,假设输入的数字都不包含重复数字,构建出满足序列的二叉树。

       树结构是我一直很头疼的一部分,感觉他是数据结构中最繁琐的了,如果我们要想学会这部分首先大家一定要明白树的结构,以及前序遍历,中序遍历,后续遍历的特点,还有就是脑子中有递归的概念。明白看这些特点我们再学树就如鱼得水了,废话不多说,大家可以看看代码,我把需要注意的地方都用注释写了下来,可能比较简陋,有问题请大家指正。

#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;
	
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值