1. 程式人生 > >根據二叉樹的前中序確定唯一的二叉樹

根據二叉樹的前中序確定唯一的二叉樹

關鍵是怎麼根據前中序推出二叉樹。假設前序為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;
}