【剑指】7.重建二叉树

题目描述

  • 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1, 2, 4, 7, 3, 5, 6, 8}和中序遍历序列{4, 7, 2, 1, 5, 3, 8, 6},则重建出二叉树并输出它的头结点。

算法分析

  • 先序遍历第一个位置肯定是根节点node, 中序遍历的根节点位置在中间p,在p左边的肯定是node的左子树的中序数组,p右边的肯定是node的右子树的中序数组;
  • 另一方面,先序遍历的第二个位置到p,也是node左子树的先序子数组,剩下p右边的就是node的右子树的先序子数组,把四个数组找出来,分左右递归调用即可。

提交代码:

class Solution {
public:
	TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) 
	{
		if (pre.empty() || vin.empty() || pre.size() != vin.size())
			return nullptr;

		TreeNode* root = reConstructBinaryTreeCore(
			pre.begin(), pre.end(), vin.begin(), vin.end());

		return root;
	}

	TreeNode* reConstructBinaryTreeCore(vector<int>::iterator start_pre, vector<int>::iterator end_pre, vector<int>::iterator start_vin, vector<int>::iterator end_vin) 
	{
		if (start_pre == end_pre || start_vin == end_vin)
			return nullptr;
		int rootVal = *start_pre;
		int rootIndex = getIndexInVin(rootVal, start_vin, end_vin);
		// 提交时需要去除
		if (rootIndex == -1)
			throw exception("Invalid input.");

		TreeNode* root = new TreeNode(rootVal);

		root->left = reConstructBinaryTreeCore(start_pre + 1, start_pre + rootIndex + 1, 
			start_vin, start_vin + rootIndex);
		root->right = reConstructBinaryTreeCore(start_pre + rootIndex + 1, end_pre, 
			start_vin + rootIndex + 1, end_vin);

		return root;
	}

	//获取中序遍历中根节点的位置,也是左子数的长度
	int getIndexInVin(int rootVal, vector<int>::iterator start_vin, 
		vector<int>::iterator end_vin) 
	{
		for (auto iter = start_vin; iter < end_vin; ++iter)
		{
			if (rootVal == *iter)
				return (iter - start_vin);
		}
		// 两个序列不同
		return -1;
	}
};

测试代码:

#include<iostream>
#include<vector>
#include "TreeNode.h"

using namespace std;
/*
// 面试题7:重建二叉树
// 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输
// 入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,
// 2, 4, 7, 3, 5, 6, 8}和中序遍历序列{4, 7, 2, 1, 5, 3, 8, 6},则重建出
// 二叉树并输出它的头结点。
*/
// ====================测试代码====================
void Test(char* testName, vector<int> &preorder, vector<int> &inorder)
{
	Solution s;
	if (testName != nullptr)
		printf("%s begins:\n", testName);

	printf("The preorder sequence is: ");
	for (int i = 0; i < preorder.size(); ++i)
		printf("%d ", preorder[i]);
	printf("\n");

	printf("The inorder sequence is: ");
	for (int i = 0; i < inorder.size(); ++i)
		printf("%d ", inorder[i]);
	printf("\n");

	try
	{
		TreeNode* root = s.reConstructBinaryTree(preorder, inorder);
		PrintTree(root);

		DestroyTree(root);
	}
	catch (std::exception& exception)
	{
		printf("Invalid Input.\n");
	}
}

// 普通二叉树
//              1
//           /     \
//          2       3  
//         /       / \
//        4       5   6
//         \         /
//          7       8
void Test1()
{
	vector<int> preorder = { 1, 2, 4, 7, 3, 5, 6, 8 };
	vector<int> inorder = { 4, 7, 2, 1, 5, 3, 8, 6 };

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

// 所有结点都没有右子结点
//            1
//           / 
//          2   
//         / 
//        3 
//       /
//      4
//     /
//    5
void Test2()
{
	vector<int> preorder = { 1, 2, 3, 4, 5 };
	vector<int> inorder = { 5, 4, 3, 2, 1 };

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

// 所有结点都没有左子结点
//            1
//             \ 
//              2   
//               \ 
//                3 
//                 \
//                  4
//                   \
//                    5
void Test3()
{
	vector<int> preorder = { 1, 2, 3, 4, 5 };
	vector<int> inorder = { 1, 2, 3, 4, 5 };

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

// 树中只有一个结点
void Test4()
{
	vector<int> preorder = { 1 };
	vector<int> inorder = { 1 };

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

// 完全二叉树
//              1
//           /     \
//          2       3  
//         / \     / \
//        4   5   6   7
void Test5()
{
	vector<int> preorder = { 1, 2, 4, 5, 3, 6, 7 };
	vector<int> inorder = { 4, 2, 5, 1, 6, 3, 7 };

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

// 输入空指针
void Test6()
{
	Test("Test6", vector<int>(), vector<int>());
}

// 输入的两个序列不匹配
void Test7()
{
	vector<int> preorder = { 1, 2, 4, 5, 3, 6, 7 };
	vector<int> inorder = { 4, 2, 8, 1, 6, 3, 7 };

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

int main(int argc, char* argv[])
{
	Test1();
	Test2();
	Test3();
	Test4();
	Test5();
	Test6();
	Test7();

	return 0;
}

猜你喜欢

转载自blog.csdn.net/ansizhong9191/article/details/80383199