重建二叉樹

對於一顆二叉樹,可以根據先序遍歷(後序遍歷)和中序遍歷重新還原出二叉樹。比如前序遍歷爲{1,2,4,7,3,5,6,8},中序遍歷爲{4, 7, 2, 1,5,3,8,6}。

根據先序遍歷和中序遍歷還原二叉樹的主要思想:

1、先序遍歷序列的第一個元素必定是根節點,可以由此獲取二叉樹的根節點。

2、根據根節點,在中序遍歷序列中查找該節點,由中序遍歷的性質可知,中序遍歷中該根節點左邊的序列必定在根節點的左子樹中,而根節點右邊的序列必定在右子樹中。由此可以知道先序遍歷中左子樹以及右子樹的起止位置。

3、分別對左子樹和右子樹重複上述的過程,直至所有的子樹的起止位置相等時,說明已經到達葉子節點,遍歷完畢。


代碼如下:

#include <iostream>
using namespace std;

typedef struct node{
	int data;
	node* left;
	node* right;
}*nodePtr;

void ReBuild(int *preStart, int *preEnd, int *inStart, int *inEnd, nodePtr &rootPtr)
{
	if (preStart > preEnd || inStart > inEnd || !preStart || !inStart)
		return;
	else
	{
		int rootVal = *preStart;
		int *rootIndex = find(inStart, inEnd, rootVal);
		rootPtr = new node;
		rootPtr->data = rootVal;
		rootPtr->left = NULL;
		rootPtr->right = NULL;
		if (rootIndex != inEnd + 1)
		{
			int leftLen = rootIndex - inStart;
			ReBuild(preStart + 1, preStart + leftLen, inStart, rootIndex - 1, rootPtr->left);
			ReBuild(preStart + leftLen + 1, preEnd, rootIndex + 1, inEnd,  rootPtr->right);
		}
	}
}

void InTraverse(nodePtr &a)
{
	if (a != NULL)
	{
		InTraverse(a->left);
		cout << a->data << endl;
		InTraverse(a->right);
	}
}


int main()
{
	int pre[] = { 1, 2, 4, 7, 3, 5, 6, 8};
	int in[] = { 4, 7, 2, 1, 5, 3, 8, 6 };
	nodePtr rootPtr = NULL;
	ReBuild(pre, pre + 7, in, in + 7, rootPtr);
	InTraverse(rootPtr);
	system("pause");
	return 0;
}

發佈了38 篇原創文章 · 獲贊 4 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章