题目来自剑指Offer和编程之美
题目:
对应的图:
思路:
根据前序遍历找出根,根据中序遍历找出左右子树区间。边缩小区间边生成树结点,直到树建立完成
注意:
在两个数组中在计算左右子树的区间时,需要通过记录子树中结点的个数获得。
代码:
BinaryTreeNode* Construct(int* pPreOrder,int* pInorder,int nLen)
{
assert(pPreOrder && pInorder && nLen > 0);
return Construct(pPreOrder,0,nLen - 1,pInorder,0,nLen - 1);
}
BinaryTreeNode* Construct(int* pPreOrder,int nPreStart,int nPreEnd,int* pInorder,int nInStart,int nInEnd)
{
//出口
if (nInStart > nInEnd)
{
return NULL;
}
//根据先序序列,找到根结点
int nRootValue = pPreOrder[nPreStart];
//在中序序列中找到根结点
int nCount = 0;
int nCur = 0;
for (nCur = nInStart;nCur <= nInEnd;nCur++)
{
if (nRootValue != pInorder[nCur])
{
nCount++;
}
else
{
break;
}
}
assert(nCur >= nInStart && nCur <= nInEnd);
//创建结点
BinaryTreeNode* pNode = new BinaryTreeNode;
pNode->m_nValue = nRootValue;
//根据中序序列,划分两个序列,递归处理。
pNode->m_pLeft = Construct(pPreOrder,nPreStart + 1,nPreStart + nCount,pInorder,nInStart,nInStart + nCount - 1);
pNode->m_pRight = Construct(pPreOrder,nPreStart + nCount + 1,nPreEnd,pInorder,nInStart + nCount + 1,nInEnd);
return pNode;
}
测试代码:
#include <iostream>
#include <assert.h>
using namespace std;
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
BinaryTreeNode* Construct(int* pPreOrder,int nPreStart,int nPreEnd,int* pInorder,int nInStart,int nInEnd)
{
//出口
if (nInStart > nInEnd)
{
return NULL;
}
//根据先序序列,找到根结点
int nRootValue = pPreOrder[nPreStart];
//在中序序列中找到根结点
int nCount = 0;
int nCur = 0;
for (nCur = nInStart;nCur <= nInEnd;nCur++)
{
if (nRootValue != pInorder[nCur])
{
nCount++;
}
else
{
break;
}
}
assert(nCur >= nInStart && nCur <= nInEnd);
//创建结点
BinaryTreeNode* pNode = new BinaryTreeNode;
pNode->m_nValue = nRootValue;
//根据中序序列,划分两个序列,递归处理。
pNode->m_pLeft = Construct(pPreOrder,nPreStart + 1,nPreStart + nCount,pInorder,nInStart,nInStart + nCount - 1);
pNode->m_pRight = Construct(pPreOrder,nPreStart + nCount + 1,nPreEnd,pInorder,nInStart + nCount + 1,nInEnd);
return pNode;
}
BinaryTreeNode* Construct(int* pPreOrder,int* pInorder,int nLen)
{
assert(pPreOrder && pInorder && nLen > 0);
return Construct(pPreOrder,0,nLen - 1,pInorder,0,nLen - 1);
}
void PreOrderT(BinaryTreeNode* pNode)
{
if (pNode)
{
cout<<pNode->m_nValue<<" ";
PreOrderT(pNode->m_pLeft);
PreOrderT(pNode->m_pRight);
}
}
void InOrderT(BinaryTreeNode* pNode)
{
if (pNode)
{
InOrderT(pNode->m_pLeft);
cout<<pNode->m_nValue<<" ";
InOrderT(pNode->m_pRight);
}
}
int main()
{
//正常二叉树
int PreOrder[8] = {1,2,4,7,3,5,6,8};
int InOrder[8] = {4,7,2,1,5,3,8,6};
BinaryTreeNode* pRoot = Construct(PreOrder,InOrder,8);
//右单支
/*int PreOrder[6] = {1,2,3,4,5,6};
int InOrder[6] = {1,2,3,4,5,6};
BinaryTreeNode* pRoot = Construct(PreOrder,InOrder,6);*/
//左单支
/*int PreOrder[6] = {1,2,3,4,5,6};
int InOrder[6] = {6,5,4,3,2,1};
BinaryTreeNode* pRoot = Construct(PreOrder,InOrder,6);*/
cout<<"PreOrder: ";
PreOrderT(pRoot);
cout<<endl<<"InOrder: ";
InOrderT(pRoot);
cout<<endl;
system("pause");
return 1;
}