根据前序遍历,中序遍历构建二叉树

文章作者:Slyar 文章来源:Slyar Home (www.slyar.com) 转载请注明,谢谢合作。

今天数据结构课讲树的存储和遍历,老师讲的很简单,也没什么代码要发...唯一看到一个比较重要的东西,总结一下算法好了。

这种题一般有二种形式,共同点是都已知中序序列。如果没有中序序列,是无法唯一确定一棵树的,证明略。

一、已知二叉树的前序序列和中序序列,求解树。

1、确定树的根节点。树根是当前树中所有元素在前序遍历中最先出现的元素。

2、求解树的子树。找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点左边和右边都为空,则根节点已经为叶子节点。

3、递归求解树。将左子树和右子树分别看成一棵二叉树,重复1、2、3步,直到所有的节点完成定位。

二、已知二叉树的后序序列和中序序列,求解树。

1、确定树的根。树根是当前树中所有元素在后序遍历中最后出现的元素。

2、求解树的子树。找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点左边和右边都为空,则根节点已经为叶子节点。

3、递归求解树。将左子树和右子树分别看成一棵二叉树,重复1、2、3步,直到所有的节点完成定位。

举例说明:根据已知求解二叉树

中序序列 BDCEAFHG
后序序列 DECBHGFA

1、BDCEAFHG在后序序列中最后出现的元素为A,BDCE|A|FHG
2、BDCE在后序序列中最后出现的元素为B,|B|DCE|A|FHG
3、FHG在后序序列中最后出现的元素为F,|B|DCE|A||F|HG
4、DCE在后序序列中最后出现的元素为C,|B|D|C|E|A||F|HG
5、HG在后序序列中最后出现的元素为G,|B|D|C|E|A||F|H|G|
6、所有元素都已经定位,二叉树求解完成。

                 A
/ \
B F
\ \
C G
/ \ /
D E H

编程之美上讲解的算法实现
#include <iostream>
using namespace std;
#define TREELEN 6
struct NODE{
	NODE *pLeft;
	NODE *pRight;
	char chValue;
};
void ReBuild(char *pPreOrder,char *pInOrder,int nTreeLen,NODE** pRoot)
{
	if (pPreOrder == NULL || pInOrder == NULL)//检查边界条件
	{
		return;
	}
	NODE* pTemp = new NODE;//获得前序遍历的第一个节点
	pTemp->chValue = *pPreOrder;
	pTemp->pLeft = NULL;
	pTemp->pRight = NULL;
	if (*pRoot == NULL)//如果节点为空,就把当前节点复制到根节点
	{
		*pRoot = pTemp;
	}
	if (nTreeLen == 1)//如果长度为1,那么已经是最后一个节点
	{
		return;
	}
	char *pOrgInorder = pInOrder;//寻找子树的长度
	char *pLeftEnd = pInOrder;
	int nTemplen = 0;
	while(*pPreOrder!=*pLeftEnd)//找到左子树的结尾
	{
		if (pPreOrder == NULL || pLeftEnd == NULL)
		{
			return;
		}
		nTemplen++;
		if (nTemplen > nTreeLen)
		{
			break;
		}
		pLeftEnd++;
	}
	int nLeftLen = 0;
	nLeftLen = (int)(pLeftEnd - pOrgInorder);
	int nRighLen = 0;
	nRighLen = nTreeLen - nLeftLen - 1;
	if (nLeftLen > 0)
	{
		ReBuild(pPreOrder+1,pInOrder,nLeftLen,&(*pRoot)->pLeft);
	}
	if (nRighLen > 0)
	{
		ReBuild(pPreOrder+nLeftLen+1,pInOrder+nLeftLen+1,nRighLen,&((*pRoot)->pRight));
	}
}
void PreOrderTraverse(NODE **t)
{
	if(!(*t)) return;
	printf("%c\n",(*t)->chValue);
	PreOrderTraverse(&((*t)->pLeft));
	PreOrderTraverse(&((*t)->pRight));
}
int main()
{
	char szPreOrder[TREELEN] = {'a','b','d','c','e','f'};
	char szInOrder[TREELEN] = {'d','b','a','e','c','f'};
	NODE * pRoot = NULL;
	ReBuild(szPreOrder,szInOrder,TREELEN,&pRoot);
	PreOrderTraverse(&(pRoot));
	system("pause");
}

  

posted @ 2012-04-19 22:46  foreverlearn  阅读(481)  评论(0编辑  收藏  举报