题目:
输入某二叉树的前序和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含有重复的数字。重建后输出其头结点。
二叉树结点定义如下:
struct BinaryTreeNode{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
解答:
仔细观察前序遍历和中序遍历的特征,有下面几个特点:
1.前序遍历中的第一个数x对应根结点
2.找到x在中序遍历中的位置,如果该位置pos1左边还有数字,则pos1左边的元素均在x对应结点的左子树中。
3.如果pos1对应位置的后边还有元素,则这些元素均在x对应结点的右子树中。
后面重复上面的过程。
实现如下:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
struct BinaryTreeNode{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
BinaryTreeNode() :m_pLeft(NULL), m_pRight(NULL){}
};
BinaryTreeNode* subTree(int *startPre, int* endPre,int* startIn, int* endIn)
{
BinaryTreeNode* root = new BinaryTreeNode;
root->m_nValue = *startPre;
if (startPre == endPre) return root;
int *rootPos = startIn;
while (rootPos <= endIn && *rootPos != *startPre) ++rootPos; //在中序遍历中找到新的根结点的值
int leftLength = rootPos - startIn;
int *leftPreEnd = startPre + leftLength;
if (leftLength > 0) root->m_pLeft = subTree(startPre + 1, leftPreEnd, startIn, rootPos - 1);
if (leftLength < endPre - startPre) root->m_pRight = subTree(leftPreEnd + 1, endPre, rootPos + 1, endIn);
return root;
}
BinaryTreeNode* reBuiltTree(int* pre, int* in,int size)
{
if (size < 1) return NULL;
return subTree(pre, pre + size - 1, in, in + size - 1);
}
void posDisplay(BinaryTreeNode *root)
{
if (root == NULL) return;
posDisplay(root->m_pLeft);
posDisplay(root->m_pRight);
cout << root->m_nValue << endl;
}
int main()
{
int pre[] = { 1, 2, 4, 7, 3, 5, 6, 8 };
int in[] = { 4, 7, 2, 1, 5, 3, 8, 6 };
BinaryTreeNode* root = reBuiltTree(pre,in,8);
posDisplay(root);
return 0;
}