由遍历序列构造二叉树

由二叉树的先序+中序、后序+中序、层次+中序都可以唯一的确定一棵二叉树。需要注意的是,如果只知道二叉树的先序序列和后序序列是无法唯一确定一棵二叉树的。

题意:输入某二叉树的先序遍历和中序遍历结果,请重建出该二叉树,并输出它的后序遍历序列。

解题思路:在二叉树的先序遍历中,第一个数字是根结点,在中序遍历中,根结点在序列的中间,左子树在根结点的左边,右子树在根结点的右边。因此可以通过扫描中序序列,找到根结点,可以得到左子树及其右子树的结点集,也即得到了左、右子树的先序遍历序列和中序遍历序列,利用递归的方法来完成。代码如下:

//由遍历序列构造二叉树
//输入某二叉树的先序遍历和中序遍历的结果,请重建出该二叉树。
//假设输入的先序遍历和终序遍历的结果中都不含重复的数字。

<pre name="code" class="cpp">#include<iostream>
using namespace std;

typedef struct BiTreeNode{
	int data;
	BiTreeNode *lchild;
	BiTreeNode *rchild;
}*BiTree;

//函数声明
BiTreeNode* Construct(int *preorder, int *inorder, int length);
BiTreeNode* ConstructCore(int *startPreorder,int *endPreorder,int *startInorder,int *endInorder);
void PostorderPrint(BiTreeNode *root);

void main()
{
	int p[]={1,2,4,7,3,5,6,8};
	int i[]={4,7,2,1,5,3,8,6};
	int *pre=p;//先序序列
	int *in=i;//中序序列
	int length=8;
	BiTreeNode *root=Construct(pre,in,length);
	cout<<"construct success!"<<endl;
	PostorderPrint(root);
}

//构建一颗二叉树
//已知先序遍历序列preorder,中序遍历序列inorder,以及长度length
BiTreeNode* Construct(int *preorder, int *inorder, int length)
{
	if(preorder==NULL || inorder==NULL || length<=0)
		return NULL;
	return ConstructCore(preorder,preorder+length-1,inorder,inorder+length-1);
}

//递归函数,构建一颗二叉树
//参数分别为:startPreorder是先序遍历的始结点,endPreorder是先序遍历的尾结点
//startInorder是中序遍历的始结点,endInorder是中序遍历的尾结点
BiTreeNode* ConstructCore(int *startPreorder,int *endPreorder,int *startInorder,int *endInorder)
{
	//先序遍历的第一个数字是根结点,首先构造根结点
	BiTreeNode *root=new BiTreeNode();
	root->data=*startPreorder;
	root->lchild=NULL;
	root->rchild=NULL;
	//递归终止条件:先序遍历中只有一个结点
	if(startPreorder==endPreorder)
		return root;
	//在中序遍历中找到根结点
	int *rootInorder=startInorder;
	while(rootInorder<=endInorder&&(*rootInorder)!=root->data)
		rootInorder++;
	if(*rootInorder!=root->data)//非法输入!
		exit(0);
	int leftlength=rootInorder-startInorder;//左子树的结点数
	if(leftlength>0)//左子树不为空,构造左子树
		root->lchild=ConstructCore(startPreorder+1,startPreorder+leftlength,startInorder,rootInorder-1);
	int rightlength=endInorder-rootInorder;//右子树的结点数
	if(rightlength>0)//右子树不为空,构造右子树
		root->rchild=ConstructCore(endPreorder-rightlength+1,endPreorder,rootInorder+1,endInorder);
	return root;
}

//以后序序列输出
void PostorderPrint(BiTreeNode *root)
{
	if(root==NULL)
		return;
	PostorderPrint(root->lchild);
	PostorderPrint(root->rchild);
	cout<<root->data<<" ";
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值