6+重建二叉树

title:
输入二叉树的前序和中序的遍历结果,要求重建该二叉树


thought:

一般涉及到二叉树(左右子树)的操作,都会考虑用到递归方法;
1、创建一个新节点,由前序得到根节点,将其赋给新节点,再找到根节点在中序中的位置root_in,根据这一位置计算出左子树的长度len;
   当数中只剩下一个节点时,就返回这一节点,此语句是递归结束语句;!!
2、根据左子树的长度计算出左子树的尾节点在位于前序的位置;
3、当左子树确定后,如果左子树的长度<整个树的长度,说明右子树不为空;
   前序中:根节点之后的前len个节点为左子树,后面的属于右子树;
   中序中:root_in前面的属于左子树,后面的属于右子树;
4、在3中的左右子树中分别循环1、2、3操作(递归);

注:
需要考虑的特殊情况:
输入的二叉树为空
单节点二叉树
无左子树的二叉树
无右子树的二叉树

前序和中序不匹配的二叉树

#include <iostream>
#include <string>
using namespace std;
struct Btree
{
	int b_value;
	Btree *b_left;
	Btree *b_right;
};

Btree *Rebuild(int *Preorder,int *Inorder,int len); //输入前序和中序序列,重建二叉树
Btree *Rebuild_subtree(int *start_pre,int *end_pre,int *start_in,int *end_in);   //重建二叉树函数中的核心递归实现
void pre_traverse(Btree *bt);
void in_traverse(Btree *bt);
void post_traverse(Btree *bt);

Btree *Rebuild(int *Preorder,int *Inorder,int len)
{
	if(NULL == Preorder || NULL == Inorder || len <= 0)
		return NULL;
	return Rebuild_subtree(Preorder,Preorder+len-1,Inorder,Inorder+len-1);
	
}
Btree *Rebuild_subtree(int *start_pre,int *end_pre,int *start_in,int *end_in)
{
	Btree *root = new Btree;                 //创建一个头结点(前序遍历的第一个结点就是头结点)
	root->b_left = NULL;
	root->b_right = NULL;
	root->b_value = start_pre[0];
	int root_value = start_pre[0];
	if(start_pre == end_pre)        
	{
		if(start_in == end_in && *start_pre == *start_in) //判断二叉树中是否为单结点
			return root;
		else
			throw exception("Invaild input!");           //抛出异常
	}
	int *root_in = start_in;                           //从前序中获得头结点的value
	while (root_value != *root_in && start_in <= end_in)   //在中序中找到值等于value的结点,此节点前面的就是左子树,后面的就是右子树
		root_in++;
	if(root_in == end_in && *root_in != *end_in)    //当根结点指针与中序的最后结点指针指向同一个地址,但是其各自的值不相等,则抛出一个异常!(即输入的前序和中序不匹配)
		throw exception("Invaild input!");
	int left_length = root_in-start_in;                   //计算左子树的长度
	int *left_end_pre = start_pre+left_length;           //根据左子树的长度计算出左子树在前序中的截止位置(由头结点的下一个节点开始,到截止位置,此序列为头结点的左子树)
	if(left_length > 0)                             //当左子树存在时,在左子树中递归重建
		root->b_left = Rebuild_subtree(start_pre+1,left_end_pre,start_in,root_in-1);
	if(left_length < end_pre-start_pre)           //当右子树存在时,在右子树中递归重建
		root->b_right = Rebuild_subtree(left_end_pre+1,end_pre,root_in+1,end_in);
	return root;
}

void pre_traverse(Btree *bt)
{
	if(NULL == bt)
	{
		cout <<"二叉树为空!" << endl;
		return;
	}
	cout<< "  " <<bt->b_value;
	if(bt->b_left != NULL)
		 pre_traverse(bt->b_left);
	if(bt->b_right != NULL)
		 pre_traverse(bt->b_right);
}

void in_traverse(Btree *bt)
{
	if(NULL == bt)
	{
		cout <<"二叉树为空!" << endl;
		return;
	}
	if(bt->b_left != NULL)
		 in_traverse(bt->b_left);
	cout<< "  " <<bt->b_value;
	if(bt->b_right != NULL)
		 in_traverse(bt->b_right);
}

void post_traverse(Btree *bt)
{
	if(NULL == bt)
	{
		cout <<"二叉树为空!" << endl;
		return;
	}
	if(bt->b_left != NULL)
		 post_traverse(bt->b_left);
	if(bt->b_right != NULL)
		 post_traverse(bt->b_right);
	 cout<< "  " <<bt->b_value;
}

int main()
{
	/*普通二叉树*/
	//int Pre[] = {1,2,4,7,3,5,6,8};
	//int In[] = {4,7,2,1,5,3,8,6};
	/*无右子树的二叉树(所有节点都无右子树)*/
	//int Pre[] = {1,2,3,4};
	//int In[] = {4,3,2,1};
	/*无左子树的二叉树(所有节点都无左子树)*/
	//int Pre[] = {1,2,3,4};
	//int In[] = {1,2,3,4};
	/*前序和后序不匹配的二叉树*/
	int Pre[] = {1,2,4,7,3,5,6,8};
	int In[] = {4,7,2,1,9,3,8,6}; //抛出异常
	int Len = sizeof(Pre)/sizeof(int);
	Btree *bt = Rebuild(Pre,In,Len);
	cout << "重建二叉树的前序遍历结果:" << endl;
	pre_traverse(bt);
	cout << endl;
	cout << "重建二叉树的中序遍历结果:" << endl;
	 in_traverse(bt);
	 cout << endl;
	cout << "重建二叉树的后序遍历结果:" << endl;
	post_traverse(bt);
	cout << endl;
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值