面試題: 給出一個前序序列 和 中序序列 重建出這顆二叉樹
思路: 通過前序序列, 我們可以找到這顆二叉樹的 根, 找到根後 通過中序遍歷序列, 我們可以找出 這個根的 左子樹 和 右子樹 序列。
有了這層思路, 我們就可以 通過遞歸的方式分別去 構建 根 根的左子樹, 根的右子樹
如 給出:
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;
}