給出前序與中序 序列 重建二叉樹

面試題: 給出一個前序序列 和 中序序列 重建出這顆二叉樹


思路:  通過前序序列, 我們可以找到這顆二叉樹的 根, 找到根後 通過中序遍歷序列, 我們可以找出 這個根的 左子樹 和 右子樹 序列。


有了這層思路, 我們就可以 通過遞歸的方式分別去 構建 根 根的左子樹,  根的右子樹


給出:

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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章