面试题: 给出一个前序序列 和 中序序列 重建出这颗二叉树
思路: 通过前序序列, 我们可以找到这颗二叉树的 根, 找到根后 通过中序遍历序列, 我们可以找出 这个根的 左子树 和 右子树 序列。
有了这层思路, 我们就可以 通过递归的方式分别去 构建 根 根的左子树, 根的右子树
如 给出:
int preorderSequence[] = { 1, 2, 4, 7, 3, 5, 6, 8 };
int InorderSequence[] = { 4, 7, 2, 1, 5, 3, 8, 6 };
我们根据, 前序 得知这棵树的 根是1 通过中序 得知 4721 是它左子树序列, 5386是它右子树序列
然后 递归 通过前序(根 左右) 我们得知 根的左子树, 的根节点为2 , 接着重复前面思路即可。
给出代码, 会比较好理解:
#include <iostream>
#include <windows.h>
using namespace std;
//注意,如果不是在类里面,如果是用面向过程思想写代码 -->> 函数需要先声明,再使用(即顺序: 声明->定义->main( ))!
//而且注意, 函数声明要放在 结点 定义之下
struct BinaryTreeNode
{
int _data;
BinaryTreeNode* _left;
BinaryTreeNode* _right;
BinaryTreeNode( int data, BinaryTreeNode* left = NULL, BinaryTreeNode* right = NULL )
: _data( data )
, _left( left )
, _right( right )
{}
};
BinaryTreeNode* ConstructCore( int* startPreorder, int* endPreorder, int* startInorder, int* endInorder );
BinaryTreeNode* Construct( int* preorder, int* inorder, int length )
{
if ( NULL == preorder || NULL == inorder || length <= 0 )
return NULL;
return ConstructCore( preorder, preorder+length-1, inorder, inorder+length-1 );
}
BinaryTreeNode* ConstructCore( int* startPreorder, int* endPreorder
, int* startInorder, int* endInorder )
{
int rootValue = startPreorder[0];
BinaryTreeNode* root = new BinaryTreeNode( rootValue );
//如果只有一个数据,就返回这个结点
if ( startPreorder == endPreorder )
{
if ( startInorder == endInorder && *startInorder == *startPreorder )
return root;
else
throw std::exception( "输入数据有误" );
}
int* rootInorder = startInorder;
//中序遍历中找到根结点的值
while ( rootInorder <= endInorder && rootValue != *rootInorder )//常量写在 左边
++rootInorder;
if ( rootInorder > endInorder )
throw std::exception( "输入数据有误." );
int leftLength = rootInorder - startInorder;
int* leftPreorderEnd = startPreorder + leftLength;
//构建 root 的左子树
if ( leftLength > 0 )
{
root->_left = ConstructCore( startPreorder+1, leftPreorderEnd, startInorder, rootInorder-1 );
}
if ( leftLength < endPreorder - startPreorder )
{
root->_right = ConstructCore( leftPreorderEnd+1, endPreorder, rootInorder+1, endInorder );
}
return root;
}
//中序遍历打印
void PrintBinaryTree( BinaryTreeNode* root )
{
if ( NULL == root )
return;
PrintBinaryTree( root->_left );
cout << root->_data << " ";
PrintBinaryTree( root->_right );
}
void TestConstructBinaryTree( )
{
int preorderSequence[] = { 1, 2, 4, 7, 3, 5, 6, 8 };
int InorderSequence[] = { 4, 7, 2, 1, 5, 3, 8, 6 };
BinaryTreeNode* root = Construct( preorderSequence, InorderSequence, sizeof(InorderSequence)/sizeof(InorderSequence[0]) );
PrintBinaryTree( root );
cout << endl;
}
int main( )
{
TestConstructBinaryTree( );
system( "pause" );
return 0;
}