给出前序与中序 序列 重建二叉树

面试题: 给出一个前序序列 和 中序序列 重建出这颗二叉树


思路:  通过前序序列, 我们可以找到这颗二叉树的 根, 找到根后 通过中序遍历序列, 我们可以找出 这个根的 左子树 和 右子树 序列。


有了这层思路, 我们就可以 通过递归的方式分别去 构建 根 根的左子树,  根的右子树


给出:

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


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