根据前序遍历,中序遍历构建二叉树
文章作者: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");
}
浙公网安备 33010602011771号