1. 程式人生 > >輸入某二叉樹的前序遍歷和中序遍歷的結果,重建該二叉樹

輸入某二叉樹的前序遍歷和中序遍歷的結果,重建該二叉樹

題目:輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。

 

思路:

 

       先序遍歷的第一個元素為根節點,在中序遍歷中找到這個根節點,從而可以將中序遍歷分為左右兩個部分,左邊部分為左子樹的中序遍歷,右邊部分為右子樹的中序遍歷,進而也可以將先序遍歷除第一個元素以外的剩餘部分分為兩個部分,第一個部分為左子樹的先序遍歷,第二個部分為右子樹的先序遍歷。

       由上述分析結果,可以遞迴呼叫構建函式,根據左子樹、右子樹的先序、中序遍歷重建左、右子樹。

完整程式碼及其測試用例實現:

#include<iostream>
#include <exception>//異常處理類
using namespace std;

//二叉樹節點定義
struct BinaryTreeNode
{
	int m_nValue;
	BinaryTreeNode* m_pLeft;
	BinaryTreeNode* m_pRight;
};

//列印樹節點
void PrintTreeNode(BinaryTreeNode* pNode)
{
	if (pNode != NULL)
	{
		cout << "value of this root node is: " << pNode->m_nValue << endl;

		if (pNode->m_pLeft != NULL)
		{
			cout << "value of its left child is: " << pNode->m_pLeft->m_nValue << endl;
		}
		else
		{
			cout << "left child is null. " << endl;
		}

		if (pNode->m_pRight != NULL)
		{
			cout << "value of its right child is: " << pNode->m_pRight->m_nValue << endl;
		}
		else
		{
			cout << "right child is null. " << endl;
		}
	}
	else
	{
		cout << "this root node is null. " << endl;
	}

	cout << endl;
}

//遍歷樹
void PrintTree(BinaryTreeNode* pRoot)
{
	PrintTreeNode(pRoot);

	if (pRoot != NULL)
	{
		if (pRoot->m_pLeft != NULL)
		{
			PrintTree(pRoot->m_pLeft);
		}

		if (pRoot->m_pRight != NULL)
		{
			PrintTree(pRoot->m_pRight);
		}
	}
}

//銷燬樹
void DestroyTree(BinaryTreeNode* pRoot)
{
	if (pRoot != NULL)
	{
		BinaryTreeNode* pLeft = pRoot->m_pLeft;
		BinaryTreeNode* pRight = pRoot->m_pRight;

		delete pRoot;
		pRoot = NULL;

		DestroyTree(pLeft);
		DestroyTree(pRight);
	}
}

//重建二叉樹
BinaryTreeNode* ConstructCore(int* startPreorder, int* endPreorder,int* startInorder, int* endInorder)
{
	// 前序遍歷序列的第一個數字是根結點的值
	int rootValue = startPreorder[0];
	BinaryTreeNode* root = new BinaryTreeNode();
	root->m_nValue = rootValue;
	root->m_pLeft = NULL;
	root->m_pRight = NULL;

	if (startPreorder == endPreorder)
	{
		if (startInorder == endInorder && *startPreorder == *startInorder)
		{
			return root;
		}
		else
		{
			throw std::exception("Invalid input.");
		}
	}

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

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

	int leftLength = rootInorder - startInorder;
	int* leftPreorderEnd = startPreorder + leftLength;
	if (leftLength > 0)
	{
		// 構建左子樹
		root->m_pLeft = ConstructCore(startPreorder + 1, leftPreorderEnd,
			startInorder, rootInorder - 1);
	}
	if (leftLength < endPreorder - startPreorder)
	{
		// 構建右子樹
		root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder,
			rootInorder + 1, endInorder);
	}

	return root;
}

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

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

// ====================測試程式碼====================

void Test(char* testName, int* preorder, int* inorder, int length)
{
	if (testName != NULL)
	{
		cout << testName << " begins:" << endl;
	}
		
	cout << "The preorder sequence is:" ;
	for (int i = 0; i < length; ++i)
	{
		cout << preorder[i] << "  ";
	}
	cout <<endl;
	
	cout << "The inorder sequence is:";
	for (int i = 0; i < length; ++i)
	{
		cout << inorder[i] << "  ";
	}
	cout << endl;
	

	try
	{
		BinaryTreeNode* root = Construct(preorder, inorder, length);
		PrintTree(root);

		DestroyTree(root);
	}
	catch (std::exception& exception)
	{
		cout << " Invalid Input."<<endl;
	}
}


void Test1()
{
// 普通二叉樹
//              1
//           /     \
//          2       3  
//         /       / \
//        4       5   6
//         \         /
//          7       8

	const int length = 8;
	int preorder[length] = { 1, 2, 4, 7, 3, 5, 6, 8 };
	int inorder[length] = { 4, 7, 2, 1, 5, 3, 8, 6 };

	Test("Test1", preorder, inorder, length);
}


void Test2()
{
	// 所有結點都沒有右子結點
	//            1
	//           / 
	//          2   
	//         / 
	//        3 
	//       /
	//      4
	//     /
	//    5

	const int length = 5;
	int preorder[length] = { 1, 2, 3, 4, 5 };
	int inorder[length] = { 5, 4, 3, 2, 1 };

	Test("Test2", preorder, inorder, length);
}


void Test3()
{
// 所有結點都沒有左子結點
//            1
//             \ 
//              2   
//               \ 
//                3 
//                 \
//                  4
//                   \
//                    5
	const int length = 5;
	int preorder[length] = { 1, 2, 3, 4, 5 };
	int inorder[length] = { 1, 2, 3, 4, 5 };

	Test("Test3", preorder, inorder, length);
}

void Test4()
{
	// 樹中只有一個結點

	const int length = 1;
	int preorder[length] = { 1 };
	int inorder[length] = { 1 };

	Test("Test4", preorder, inorder, length);
}

void Test5()
{
// 完全二叉樹
//              1
//           /     \
//          2       3  
//         / \      / \
//        4   5   6   7

	const int length = 7;
	int preorder[length] = { 1, 2, 4, 5, 3, 6, 7 };
	int inorder[length] = { 4, 2, 5, 1, 6, 3, 7 };

	Test("Test5", preorder, inorder, length);
}

void Test6()
{
	// 輸入空指標
	Test("Test6", NULL, NULL, 0);
}

void Test7()
{
	// 輸入的兩個序列不匹配
	const int length = 7;
	int preorder[length] = { 1, 2, 4, 5, 3, 6, 7 };
	int inorder[length] = { 4, 2, 8, 1, 6, 3, 7 };

	Test("Test7: for unmatched input", preorder, inorder, length);
}

int main()
{
	Test1();
	Test2();
	Test3();
	Test4();
	Test5();
	Test6();
	Test7();

	system("pause");
	return 0;
}

執行結果:

Test1 begins:

The preorder sequence is:1  2  4  7  3  5  6  8

The inorder sequence is:4  7  2  1  5  3  8  6

value of this root node is: 1

value of its left child is: 2

value of its right child is: 3

value of this root node is: 2

value of its left child is: 4

right child is null.

value of this root node is: 4

left child is null.

value of its right child is: 7

value of this root node is: 7

left child is null.

right child is null.

value of this root node is: 3

value of its left child is: 5

value of its right child is: 6

value of this root node is: 5

left child is null.

right child is null.

value of this root node is: 6

value of its left child is: 8

right child is null.

value of this root node is: 8

left child is null.

right child is null.

Test2 begins:

The preorder sequence is:1  2  3  4  5

The inorder sequence is:5  4  3  2  1

value of this root node is: 1

value of its left child is: 2

right child is null.

value of this root node is: 2

value of its left child is: 3

right child is null.

value of this root node is: 3

value of its left child is: 4

right child is null.

value of this root node is: 4

value of its left child is: 5

right child is null.

value of this root node is: 5

left child is null.

right child is null.

Test3 begins:

The preorder sequence is:1  2  3  4  5

The inorder sequence is:1  2  3  4  5

value of this root node is: 1

left child is null.

value of its right child is: 2

value of this root node is: 2

left child is null.

value of its right child is: 3

value of this root node is: 3

left child is null.

value of its right child is: 4

value of this root node is: 4

left child is null.

value of its right child is: 5

value of this root node is: 5

left child is null.

right child is null.

Test4 begins:

The preorder sequence is:1

The inorder sequence is:1

value of this root node is: 1

left child is null.

right child is null.

Test5 begins:

The preorder sequence is:1  2  4  5  3  6  7

The inorder sequence is:4  2  5  1  6  3  7

value of this root node is: 1

value of its left child is: 2

value of its right child is: 3

value of this root node is: 2

value of its left child is: 4

value of its right child is: 5

value of this root node is: 4

left child is null.

right child is null.

value of this root node is: 5

left child is null.

right child is null.

value of this root node is: 3

value of its left child is: 6

value of its right child is: 7

value of this root node is: 6

left child is null.

right child is null.

value of this root node is: 7

left child is null.

right child is null.

Test6 begins:

The preorder sequence is:

The inorder sequence is:

this root node is null.

Test7: for unmatched input begins:

The preorder sequence is:1  2  4  5  3  6  7

The inorder sequence is:4  2  8  1  6  3  7

 Invalid Input.

請按任意鍵繼續. . .