面試題----重建二叉樹

一、題目:輸入某二叉樹的前序遍歷和中序遍歷的結果,重建出該二叉樹,假設無重複數字。例如前序遍歷結果爲{1,2,4,7,3,5,6,8},中序遍歷結果爲{4,7,2,1,5,3,8,6},重建出該二叉樹並輸出其頭節點。

首先看到該題目,我們心裏應該清楚二叉樹的前序遍歷和中序遍歷各自有什麼特點,想不通的話可以在紙上畫一畫。前序遍歷序列中第一個數字總是該二叉樹的根節點,但是在中序遍歷序列中根節點在中間,結合兩個序列,我們很容易就能知道二叉樹的根節點以及左右子樹,如下圖所示:
依照這種方法,第二遍查找根節點爲2,那麼在左子樹中(中序遍歷序列)可以發現2只有左子樹,接着根節點爲4時,右子樹是7......按照這種思路就可以將一棵完整的二叉樹重構出來了,不難發現,這裏用了一種遞歸的思路,重建的二叉樹如下所示:建議在紙上畫一畫

在瞭解整棵樹如何重構之後,算法代碼也就很容易能夠寫出來了,就是遞歸方法的一種實現

二叉樹節點定義:
struct BinaryTreeNode
{
	int value;
	BinaryTreeNode* pLeft;    //左節點
	BinaryTreeNode* pRight;   //右節點
};

遞歸代碼如下:
BinaryTreeNode* RebuildCore(int *startPreorder,int *endPreorder,int *startInorder,int *endInorder)
{
	int rootValue = startPreorder[0];
	BinaryTreeNode* root =new BinaryTreeNode();
	root->value = rootValue;
	root->pLeft = root->pRight = NULL;

	//判斷前序和中序遍歷中是不是隻有一個節點,若是則該樹就只有一個節點即根
	if(startPreorder == endPreorder)
	{
		if(startInorder == endInorder && *startPreorder == *startInorder)
		{
			return root;
		}
		else
		{
			throw std::exception("invailed input");
		}
	}

	//在中序遍歷中找到根節點
	int *rootInorder = startInorder;
	while (rootInorder <= endInorder && *rootInorder != rootValue)
	{
		rootInorder++;
	}

	if (rootInorder == endInorder && *rootInorder != rootValue)
	{
		throw std::exception("invailed input");
	}

	int leftLength = rootInorder - startInorder;
	int *leftInorderNow = startPreorder + leftLength;
	//構建左子樹
	if(leftLength > 0)
	{
		root->pLeft = RebuildCore(startPreorder+1,leftInorderNow,startInorder,rootInorder-1);
	}
	//構建右子樹
	if(leftLength < endPreorder - startPreorder)
	{
		root->pRight = RebuildCore(leftInorderNow+1,endPreorder,rootInorder+1,endInorder);
	}

	return root;
}

BinaryTreeNode* Rebuild(int *preorder,int *inorder,int length)
{
	if (preorder == NULL || inorder == NULL || length < 0)
	{
		return NULL;
	}

	return RebuildCore(preorder,preorder+length-1,inorder,inorder+length-1);
}


參考劍指offer上的面試題,以上就是大概的思路,感受最深的是在寫代碼之前一定要先整理好自己的思路,不要一上來就開始寫,就想着我要實現這個功能,先把思路整理好,代碼實現就是將自己的思路用另外一種語言呈現出來罷了,所以,思路很重要。沒有思路的話,在紙上畫一畫,想一想,這個問題還能不能拆分成一些更小的自己能夠解決的一些問題,然後再整合,解決一個大問題。

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