1. 程式人生 > >已知前序和中序遍歷求二叉樹

已知前序和中序遍歷求二叉樹

描述

輸入某二叉樹的前序遍歷和中序遍歷的結果,請輸出後序遍歷序列。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},重建二叉樹並返回後序遍歷序列

輸入

輸入某二叉樹的前序遍歷和中序遍歷的結果

輸出

輸出後序遍歷序列

輸入樣例 1 

1 2 4 7 3 5 6 8
4 7 2 1 5 3 8 6

輸出樣例 1

7 4 2 5 8 6 3 1

 題意:

前序遍歷即先訪問根節點,然後是左子樹,右子樹

中序遍歷為先訪問左子樹,然後是根節點,右子樹

所以通過前序遍歷不斷地找到根節點,然後中序遍歷找到其左子樹和右子樹

最後就可以得到這棵二叉樹,後序遍歷即為 7 4 2 5 8 6 3 1

實現程式碼:

#include<stdio.h>
#include<stdlib.h> 
#include<string.h> 
typedef struct node* BinTree; 
struct node{
	int date;
	BinTree left;
	BinTree right;
};
BinTree Build(int pre[] ,int in[] ,int size)
{
	if(size<=0)return NULL;
	//先在中序中找到根節點
	int i;
	for(i=0;i<size;i++)
	{
		if(in[i]==pre[0])break;
	} 
	BinTree tree=(BinTree)malloc(sizeof(struct node));
	tree->date=pre[0];
	tree->left=Build(pre+1,in,i);
	tree->right=Build(pre+i+1,in+i+1,size-1-i);
	return tree;
} 
void postorder(BinTree T)  //後序遍歷 
{
	if(T==NULL)return;
	else{
		postorder(T->left);
		postorder(T->right);
	    printf("%d ",T->date);
	}
	
} 
int main()
{
	char pree[800],inn[800];  
	gets(pree);
	gets(inn);  
	int size=strlen(pree);  
	int pre[800],in[800];
	int precount=0; 
	int i;
	for(i=0;i<size;i++)
	{
		if(i==0)
		{
			pre[precount]=pree[i]-'0';
		}
		else
		{
			if(pree[i]>='0'&&pree[i]<='9')
			{
				//此if-else 用來轉換多位數為int型別 
				if(pree[i-1]==' ')  //如果前一個元素為空格 
				{
					precount++;
				    pre[precount]=pree[i]-'0';
				}
				
				else  //如果前一個元素不是空格,那麼說明與前一個元素一同構成的數  例如:10 
				{
					pre[precount]=pre[precount]*10+(pree[i]-'0');
				}
			}
			
		}
		
	}
	int incount=0;
	for(i=0;i<size;i++)
	{
		if(i==0)
		{
			in[incount]=inn[i]-'0'; 
		}
		else
		{
			if(inn[i]>='0'&&inn[i]<='9')
			{
				if(inn[i-1]==' ')
				{
					incount++;
				    in[incount]=inn[i]-'0';
				}
				
				else
				{
					in[incount]=in[incount]*10+(inn[i]-'0');
				}
			}
			
		}
		
	}  
    //如果前序遍歷的結點數與中序遍歷的結點數相同且不為0,那麼可以找到對應二叉樹 
    if(precount==incount&&precount!=0)  
    {
    	BinTree T;
		T=Build(pre,in,precount+1);
		postorder(T);
	}
	
    
	return 0;
}