重建二叉树

输入某二叉树的前序遍历和中序遍历,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含有重复的数字。

例如,前序遍历序列:{1,2,3,7,3,5,6,8},中序遍历序列:{4,7,2,1,5,3,8,6}

根据先序遍历和中序遍历还原二叉树的主要思想:

1、先序遍历序列的第一个元素必定是根节点,可以由此获取二叉树的根节点。

2、根据根节点,在中序遍历序列中查找该节点,由中序遍历的性质可知,中序遍历中该根节点左边的序列必定在根节点的左子树中,而根节点右边的序列必定在右子树中。由此可以知道先序遍历中左子树以及右子树的起止位置。

3、分别对左子树和右子树重复上述的过程,直至所有的子树的起止位置相等时,说明已经到达叶子节点,遍历完毕。

#include<iostream.h>
#include<malloc.h>

struct treenode
{
	int date;
	treenode *leftch;
	treenode *rightch;
};

bool tree=true;

treenode *constructcore(int preorder[],int prestart,int preend,int inorder[],int instart,int inend)
{
	int rootnum=preorder[prestart];
	treenode *root=(treenode *)malloc(sizeof(treenode));
	root->date=rootnum;
	root->leftch=NULL;
	root->rightch=NULL;

	if(preend==prestart)
	{
		if(instart==inend&&preorder[prestart]==inorder[instart])
			return root;
		else
		{
			tree=false;
			return NULL;
		}
	}

	int rootinorderindex=-1;
	for(int i=instart;i<=inend;i++)
		if(inorder[i]==rootnum)
			rootinorderindex=i;

	if(rootinorderindex==-1)
	{
		tree=false;
		return NULL;
	}

	if(rootinorderindex-instart>0) //左子树不为空
		root->leftch=constructcore(preorder,prestart+1,prestart+rootinorderindex-instart,inorder,instart,rootinorderindex-1);
	if(inend-rootinorderindex>0)  //右子树不为空
		root->rightch=constructcore(preorder,prestart+rootinorderindex-instart+1,preend,inorder,rootinorderindex+1,inend);

	return root;
}

treenode *construct(int preorder[],int inorder[],int length)
{
	if(preorder==NULL||inorder==NULL||length<1)
		return NULL;
	return constructcore(preorder,0,length-1,inorder,0,length-1);
}

void preordertree(treenode *root)
{
	if(root==NULL)
		return;
	cout<<root->date<<"  ";
	preordertree(root->leftch);
	preordertree(root->rightch);
}

void inordertree(treenode *root)
{
	if(root==NULL)
		return;
	inordertree(root->leftch);
	cout<<root->date<<"  ";
	inordertree(root->rightch);
}

void main()
{
	int preorder[]={1,2,4,7,3,5,6,8},inorder[]={4,7,2,1,5,3,8,6};
	

	treenode *root=NULL;
	root=construct(preorder,inorder,sizeof(preorder)/sizeof(int));

	if(tree)
	{
		preordertree(root);
		cout<<endl;

		inordertree(root);
		cout<<endl;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值