1. 程式人生 > >根據先序序列和中序序列建立二叉樹

根據先序序列和中序序列建立二叉樹

思考:如何才能確定一棵樹?
結論:    通過中序遍歷和先序遍歷可以確定一個樹
                通過中序遍歷和後續遍歷可以確定一個樹
                通過先序遍歷和後序遍歷確定不了一個樹。
單獨先序遍歷:能求解根,但不能求解左子樹什麼時候結束、右子樹什麼時候開始。

根據先序和中序結果畫樹

演算法
1、通過先序遍歷找到根結點A,再通過A在中序遍歷的位置找出左子樹,右子樹
2、在A的左子樹中,找左子樹的根結點(在先序中找),轉步驟1
3、在A的右子樹中,找右子樹的根結點(在先序中找),轉步驟1

根據如下遍歷結果建立二叉樹:


先序遍歷結果:ABDHKECFIGJ

中序遍歷結果:HKDBEAIFCGJ


#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include<stdio.h>
#include <string.h>

#define  N  100

typedef struct BiTNode  
{  
	char data;  
	struct BiTNode *lchild,*rchild;  
} BiTNode,* BITree;  

//先序遍歷  
void preOrder(BiTNode*root)  
{  
	if (root==NULL)  
	{  
		return;  
	}  
	printf("%c ",root->data);  
	preOrder(root->lchild);  
	preOrder(root->rchild);  
}  
//中序遍歷  
void inOrder(BiTNode*root)  
{  
	if (root==NULL)  
	{  
		return;  
	}  
	inOrder(root->lchild);  
	printf("%c ",root->data);  
	inOrder(root->rchild);  
}  

/************************************************************************/
/* 演算法
1、通過先序遍歷找到根結點A,再通過A在中序遍歷的位置找出左子樹,右子樹
2、在A的左子樹中,找左子樹的根結點(在先序中找),轉步驟1
3、在A的右子樹中,找右子樹的根結點(在先序中找),轉步驟1                                                                     */
/************************************************************************/

//根據先序遍歷和中序遍歷建立二叉樹
BiTNode* createBiTree(char *pre, char *in, int n)
{
	int i = 0;
	int n1 = 0,n2 = 0;
	int m1 = 0,m2 = 0;
	BiTNode*node = NULL;
	char lpre[N],rpre[N];
	char lin[N],rin[N];
	if (n == 0)
	{
		return NULL;
	}
	node = (BiTNode*)malloc(sizeof(BiTNode));  
	if (node==NULL)  
	{  
		return NULL;  
	}  
	memset(node,0,sizeof(BiTNode)); 
	//先序序列的第一個元素必為根結點
	node->data = pre[0];
	//根據根結點將中序序列分為左子樹和右子數
	for (i = 0;i<n;i++)
	{
		if ((i<=n1)&&(in[i]!=pre[0]))
		{
			lin[n1++] = in[i];
		}
		else if(in[i]!=pre[0])
		{
			rin[n2++] = in[i];
		}
	}
	//根據樹的先序序列的長度等於中序序列的長度
	//且先序遍歷是先左子樹再後子樹,無論先序還是中序 左子樹和右子樹的長度都是固定的
	//主意 從i=1開始 因為先序遍歷的第一個是根 
	for (i = 1;i < n;i++)
	{
		if (i< (n1+1))//n1代表了左子樹的長度
		{
			lpre[m1++] = pre[i];
		}
		else
		{
			rpre[m2++] = pre[i];
		}
	}
	node->lchild = createBiTree(lpre,lin,n1);
	node->rchild = createBiTree(rpre,rin,n2);

	return node;
}

int main()
{
	char preNode[N];
	char inNode[N];
	int n = 0;
	char ch;
	BiTNode* root=NULL;
	printf("請輸入先序序列\n");
	while((ch = getchar())&&ch!='\n')
		preNode[n++] = ch;
	printf("請輸入中序序列\n");
	n = 0;
	while((ch = getchar())&&ch!='\n')
		inNode[n++] = ch;
	root = createBiTree(preNode,inNode,n);

	printf("先序序列\n");
	preOrder(root);
	printf("\n中序序列\n");
	inOrder(root);

	system("pause");
	return 0;
}