您的位置:首页 > 编程语言

编程之美读书笔记-重建二叉树

2016-08-30 19:20 323 查看
题目:给定一棵二叉树,假设每个节点都用唯一的字符来表示,具体结构如下。

struct NODE
{
NODE *pLeft;
NODE *pRight;
char chValue;
};

假设已经有了前序遍历和中序遍历的结果,希望通过一个算法重建这棵树。

给定函数的定义如下:void  Rebuild(char *pPreOrder, char *pInOrder, int nTreeLen, NODE **pRoot) 

pPreOrder:以null结尾的前序遍历结果的字符串数组。 

pInOrder:以null结尾的中序遍历结果的字符串数组。 

nTreeLen:树的长度。 

pRoot:返回node**类型,根据前序遍历和中序遍历结果重新构建树的根节点。 

例如 

前序遍历结果:abdcef 

中序遍历结果:dbaecf 

重建的树如图所示。



解析:a是前序遍历节点中的第一个元素,可以看出,它把中序遍历的结果分成db和ecf两个部分。如果能够找到前序遍历中对应的左子树和右子树,就可以把a作为当前的根节点,然后依次递归下去,这样就能够依次恢复左子树和右子树的遍历结果。

#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;
//如果节点为空,令当前节点pRoot的地址等于pTemp的地址
if (*pRoot == NULL) *pRoot = pTemp;
//如果当前树长度为1,那么已经是最后一个节点
if (nTreeLen == 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 nRightLen = 0;
nRightLen = nTreeLen - nLeftLen - 1;
//重建左子树
if (nLeftLen>0)
ReBuild(pPreOrder + 1, pInOrder, nLeftLen, &((*pRoot)->pLeft));
//重建右子树
if (nRightLen>0)
ReBuild(pPreOrder + nLeftLen + 1, pInOrder + nLeftLen + 1, nRightLen, &((*pRoot)->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);
system("PAUSE");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: