根据二叉树的前中序确定唯一的二叉树

关键是怎么根据前中序推出二叉树。假设前序为1245367,中序为4251637。那么根结点为1,在中序中找到1,则左边为1的左子树,右边为1的右子树。那么可以根据这个在前序序列中和中序序列中,分出1的左子树和右子树在进行按照1的计算方法分别计算,直到找到叶子结点。。可以确定树。关键是利用了树的递归性质。

代码实现:先建树,然后算出其前序和中序序列,最后再根据序列求出树,看是否和刚开始建的树相同,代码如下:

#include<iostream>
#include<string>
#include<stack>
#include<queue>
using namespace std;
int porder[10];
int iorder[10];
struct Btree{
	int value;
	Btree* left;
	Btree* right;
};
Btree* Build( ){
	int x;
	Btree* temp;
	scanf("%d",&x);
	if(x == 0)
		temp = NULL;
	else{
		temp = (Btree *)malloc(sizeof(Btree));
		temp->value = x;
		printf("输入%d结点的左结点\n",x);
		temp->left = Build();
		printf("输入%d结点的右结点\n",x);
		temp->right = Build();
	}
	return temp;	
}
//递归遍历
void preorder(Btree* root){
	if(root == NULL)
		return;
	int i =0;
	stack<Btree*> Bstack;
	while(root || !Bstack.empty()){
		while(root){
			porder[i++] = root->value;
			Bstack.push(root);
			root = root->left;
		}
		if(!Bstack.empty()){
			root = Bstack.top();
			Bstack.pop();
			root = root->right;
		}
	}
	for(int i =0;porder[i]!= 0;i++)
		printf("%d",porder[i]);
	printf("\n");
}
//中序遍历
void inorder(Btree* root){
	if(root == NULL)
		return;
	int i =0;
	stack<Btree*> Bstack;
	while(root || !Bstack.empty()){
		while(root){
			Bstack.push(root);
			root = root->left;
		}
		if(!Bstack.empty()){
			root = Bstack.top();
			Bstack.pop();
			iorder[i++] = root->value;
			root = root->right;
		}
	}
	for(int i =0;iorder[i]!= 0;i++)
		printf("%d",iorder[i]);
	printf("\n");
}
//层次输出树
void printTree(Btree* root){
	if(root == NULL)
		return;
	queue<Btree *> Bq;
	Bq.push(root);
	while(!Bq.empty()){
		root = Bq.front();
		Bq.pop();
		printf("%d",root->value);
		if(root->left)
			Bq.push(root->left);
		if(root->right)
			Bq.push(root->right);
	}
	printf("\n");
}
//根据前中序构建树
Btree* prBuild(int pstart,int pend,int istart,int iend){
	//空返回即叶子结点的左右子树
	if(pstart>pend || istart>iend)
		return NULL;
	Btree* root = (Btree* )malloc(sizeof(Btree));
	root->value = porder[pstart];
	int i = istart;
	for(;i<=iend;i++){
		if(iorder[i] == porder[pstart])
			break;
	}
	int leftlen = i-istart;
	int rightlen= iend-i;
	//递归左子树
	root->left = prBuild(pstart+1,pstart+leftlen,istart,istart+leftlen-1);
	//递归右子树
	root->right= prBuild(pstart+leftlen+1,pend,i+1,iend);
	return root;
}
int main(){
	Btree *root = Build();
	memset(porder,0,sizeof(porder));
	memset(iorder,0,sizeof(iorder));
	printf("前序遍历为:\n");
	preorder(root);
	printf("中序遍历为:\n");
	inorder(root);
	printf("层次遍历为:\n");
	printTree(root);
	int len =0;
	for(;porder[len]!=0;len++);
	Btree* nroot = prBuild(0,len-1,0,len-1);
	printf("根据前中序层次遍历为:\n");
	printTree(nroot);
	system("PAUSE");
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值