重建二叉树

题目 :输入某二叉树的前序遍历和中序遍历结果,请重建出该二叉树。

假设输入的前序遍历和中序遍历的结果都不含重复的数字。

思路:在二叉树的前序遍历序列中,第一个数字总是树的根节点的值。但在中序遍历中,根节点的值在序列的中间,左子树的节点再根节点的左边右子树的节点在树的右边。

1.根据前序和中序的特点得到根节点为1的左右子树图:


2.根节点1的左指针指向2的左右子树图:


3.等等都是用同样的方法来构建左右子树,也就是说,我们可以用递归的方法来实现。

代码:

#pragma once

struct BinaryTreeNode
{
	int _data;
	BinaryTreeNode* _left;
	BinaryTreeNode* _right; 
	BinaryTreeNode(const int& data)
		:_data(data)
		,_left(0)
		,_right(0)
	{}
};
typedef BinaryTreeNode Node;
//递归的思想
Node* construct(int* startpreorder,int* endpreorder,int* startinorder,int* endinorder)
{
	int rootvalue=startpreorder[0];  //根节点的值
	Node* root=new Node(rootvalue);
	
	if(startpreorder==endpreorder)    //只有一个节点
	{
		if(startinorder==endinorder&&*startpreorder==*startinorder)
			return root;
		else
		{
			return NULL;
		}
	}
	int* inorderroot=startinorder;     //在中序中找到根节点的值
	while(inorderroot<=endinorder)
	{
		if(*inorderroot==rootvalue)
			break;
		inorderroot++;
	}
	if(inorderroot==endinorder&&*inorderroot!=rootvalue)
		return NULL;
	int LeftLenght=inorderroot-startinorder;       //左树的长度
	int* LeftPreorderEnd=startpreorder+LeftLenght;   //在前序中左子树最后的一个节点
	if(LeftLenght>0)
	{
		//构建左子树
		root->_left =construct(startpreorder+1,LeftPreorderEnd,
			startinorder,inorderroot-1);
	}
	if(LeftLenght<endpreorder-startpreorder)
	{
		//构建右子树
		root->_right =construct(LeftPreorderEnd+1,
			endpreorder,inorderroot+1,endinorder);
	}
	return root;
}
Node* Construct(int* preorder,int* inorder,int length)
{
	if(preorder==NULL||inorder==NULL||length<=0)
		return NULL;
	return construct(preorder,preorder+length-1,inorder,inorder+length-1);
}
void PreOrder(Node* root)
{
	if(root==NULL)
		return;
	cout<<root->_data <<" ";
	PreOrder(root->_left );
	PreOrder(root->_right );
}
void InOrder(Node* root)
{
	if(root==NULL)
		return;
	InOrder(root->_left );
	cout<<root->_data <<" ";
	InOrder(root->_right );
}

void TestBinaryTree()
{
	/*int preorder[]={1,2,4,7,3,5,6,8};
	int inorder[]={4,7,2,1,5,3,8,6};*/
	int preorder[]={3,5,6,8};
	int inorder[]={5,3,8,6};
	Node* root=Construct(preorder,inorder,8);
    PreOrder(root);
	cout<<endl;
	InOrder(root);
	cout<<endl;
 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值