已知前序和中序遍历恢复二叉树
2013-07-17 14:51
225 查看
[cpp] view
plaincopy
#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;
}
//如果当前树长度为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));
}
}
//前序遍历结果
void PrePrint(NODE* pRoot)
{
if(pRoot == NULL)
{
return;
}
cout<<pRoot->chValue<<" ";
PrePrint(pRoot->pLeft);
PrePrint(pRoot->pRight);
}
//中序遍历结果
void InPrint(NODE* pRoot)
{
if(pRoot == NULL)
{
return;
}
InPrint(pRoot->pLeft);
cout<<pRoot->chValue<<" ";
InPrint(pRoot->pRight);
}
void 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);
PrePrint(pRoot);
cout<<endl<<endl;;
InPrint(pRoot);
cout<<endl;
}
/*
a b d c e f
d b a e c f
*/
plaincopy
#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;
}
//如果当前树长度为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));
}
}
//前序遍历结果
void PrePrint(NODE* pRoot)
{
if(pRoot == NULL)
{
return;
}
cout<<pRoot->chValue<<" ";
PrePrint(pRoot->pLeft);
PrePrint(pRoot->pRight);
}
//中序遍历结果
void InPrint(NODE* pRoot)
{
if(pRoot == NULL)
{
return;
}
InPrint(pRoot->pLeft);
cout<<pRoot->chValue<<" ";
InPrint(pRoot->pRight);
}
void 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);
PrePrint(pRoot);
cout<<endl<<endl;;
InPrint(pRoot);
cout<<endl;
}
/*
a b d c e f
d b a e c f
*/
相关文章推荐
- 二叉树 已知两种遍历恢复二叉树
- 已知前序和中序遍历恢复二叉树(递归)
- 数据结构学习笔记(9)---已知二叉树的遍历序列,恢复二叉树
- 已知前序和中序遍历恢复二叉树
- 六、树和二叉树--(3)已知先序遍历和中序遍历求后序遍历
- 已知二叉树的先序遍历(preorder)和中序遍历(inorder) 或 中序和后序(postorder),还原该二叉树
- 已知二叉树的前序遍历和中序遍历,如何得到它的后序遍历?
- 计算机技术——已知二叉树的前序遍历和中序遍历,如何得到它的后序遍历?
- 数据结构 二叉树 已知前序中序遍历求后续遍历的递归实现
- 【LeetCode91-100】编码种数,逆转单链表,IP地址转化,中序遍历二叉树,生成二叉搜索树,计算二叉树个数,交叉string【hard】,判断二叉搜索树是否合法,恢复二叉树(有两个元素被交换)
- 已知二叉树的前序和中序遍历,重构该二叉树
- 遍历序列恢复二叉树
- 【遍历二叉树】07恢复二叉搜索树【Recover Binary Search Tree】
- 已知二叉树前序,中序遍历,求后序遍历,java实现
- 已知两种遍历序列求原始二叉树
- 已知二叉树的中序和后序遍历排列,求前序遍历
- 3.9已知二叉树的 前序遍历和中序遍历的结果,重构出原二叉树
- 已知二叉树后序遍历序列是DBCEFGHA,中序遍历序列EDCBAHFG,它的前序遍历的序列是?麻烦再画下这二叉树.
- 已知先序遍历和中序遍历求后序遍历——二叉树
- 已知二叉树前序、后序遍历如何求中序