重建二叉樹

    二叉樹是咱們學習數據結構階段一個重要的知識點,二叉樹又被分爲滿二叉樹,徹底二叉樹和其它三種來學習,所謂的滿二叉樹是指咱們的二叉樹的每個非葉子節點必定含有左孩子和右孩子,而徹底二叉樹則是指咱們的樹的葉子節點必須連續的分佈在樹的左邊。算法

    今天,咱們來探索一下如何在知道二叉樹前序遍歷順序及中序遍歷順序來重建二叉樹數組

    首先,重建咱們的二叉樹,必需要找到根節點,那麼根節點應該如何找到呢。以下圖所示,根結點一定是咱們前序遍歷數組的首元素。在知道了根節點的狀況下,咱們就能夠在咱們的中序遍歷序列裏找到咱們須要的根節點所在。只要有了根節點的位置,咱們很容易就能夠肯定左樹節點個數,以及右樹的節點個數。而咱們很清楚,在二叉樹這裏咱們大多采用遞歸來解決子問題,因此顯而易見的,咱們將根節點的左子樹和右子樹轉換成爲子問題來解決更加容易理解。
數據結構

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
學習

相關文章
相關標籤/搜索