重建二叉树

    二叉树是咱们学习数据结构阶段一个重要的知识点,二叉树又被分为满二叉树,彻底二叉树和其它三种来学习,所谓的满二叉树是指咱们的二叉树的每个非叶子节点必定含有左孩子和右孩子,而彻底二叉树则是指咱们的树的叶子节点必须连续的分布在树的左边。算法

    今天,咱们来探索一下如何在知道二叉树前序遍历顺序及中序遍历顺序来重建二叉树数组

    首先,重建咱们的二叉树,必需要找到根节点,那么根节点应该如何找到呢。以下图所示,根结点一定是咱们前序遍历数组的首元素。在知道了根节点的状况下,咱们就能够在咱们的中序遍历序列里找到咱们须要的根节点所在。只要有了根节点的位置,咱们很容易就能够肯定左树节点个数,以及右树的节点个数。而咱们很清楚,在二叉树这里咱们大多采用递归来解决子问题,因此显而易见的,咱们将根节点的左子树和右子树转换成为子问题来解决更加容易理解。
数据结构

wKioL1cp4Ljgs5RrAAALCZNRp2Y032.png

    下面我给出了本题的详细代码以及注释j_0046.gif
ide

struct BinaryTreeNode
{
	int _value;
	BinaryTreeNode *_left;
	BinaryTreeNode *_right;
	BinaryTreeNode(const int& x = 0) :_value(x), _left(NULL), _right(NULL)
	{}
};
class BinaryTree
{
private:
	BinaryTreeNode *_root;
public:
	BinaryTree()
	{}
	BinaryTree(int *PreOrder, int *InOrder,int size)
	{
		if (!PreOrder || !InOrder || size <= 0)
			return;
		_root = _CreateTree(PreOrder, PreOrder + size - 1, InOrder, InOrder + size - 1);
	}
private:
	BinaryTreeNode* _CreateTree(int *Pre,int *endPre,int *In,int *endIn)
	{
		//构造当前根节点root 
		int RootValue = Pre[0];
		BinaryTreeNode *root = new BinaryTreeNode(RootValue);
		
		//当走到最后一个元素
		if (Pre == endPre)
		{
			//若是中序也走到了最后一个节点
			//最后一个节点相等说明最后一个节点是一个右分支
			if (In == endIn && *Pre == *In)
				return root;
		}

		//在中序遍历中找到根节点
		int *rootIn = In;
		while (rootIn <= endIn && *rootIn != RootValue)
		{
			//当它等于前序首元素时表示为中序的根节点
			++rootIn;
		}
		//找到以后计算出左子树的节点数
		int leftLen = rootIn - In;

		//找出前序里左子树的构造区间
		int *PreLeftEnd = Pre + leftLen;
		if (leftLen > 0)
		{
			//构造左子树
			root->_left = _CreateTree(Pre + 1, PreLeftEnd  , In, rootIn - 1);
		}

		if (leftLen < endPre - Pre)
		{
			//构造右子树
			root->_right = _CreateTree(PreLeftEnd + 1, endPre, rootIn + 1, endIn);
		}
		return root;

	}
};
int main()
{
	int Pre[] = { 1, 2, 4, 5, 3, 6 };
	int In[] = { 4, 2, 5, 1, 6, 3};
	BinaryTree tree(Pre, In, sizeof(Pre) / sizeof(Pre[0]));
	getchar();
	return 0;
}

    若是实在不能理解建议在纸上将整个过程整理一遍,相信这样就会对树的创建以及递归的算法有深入的理解,显然博主就常常这么作~j_0048.gif
学习

相关文章
相关标签/搜索