4.重建二叉树

重建二叉树
  • 参与人数:5402时间限制:1秒空间限制:32768K
  •  算法知识视频讲解

题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
我没有按照书上的做法来解,而是采用long型指针来存储地址,虽然很绕,但是可以熟悉指针的使用。牛客网使用的是64位编译器,故不能用int数组存地址,而要使用long型数组。
<pre name="code" class="cpp">// 4.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <vector>

using namespace::std;

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution {
public:
	struct TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> in) {
		if (pre.size() <= 0 || in.size() <= 0) return NULL;
		if (pre.size() != in.size()) return NULL;

		int length = pre.size(); // 获得数组的长度

		long* pPre = new long[length];
		int i = 0;
		for (vector<int>::iterator iter = pre.begin(); iter != pre.end(); iter++){
			pPre[i] = (long)&(*iter);// *iter取迭代器中的内容,&(*iter)取该内容的地址,(long)&(*iter)把地址转化为long型
			i++;
		}

		long* pIn = new long[length]; // 动态分配数组内存
		i = 0;
		for (vector<int>::iterator iter = in.begin(); iter != in.end(); iter++){
			pIn[i] = (long)&(*iter);
			i++;
		}

		TreeNode* root = ConstructCore(pPre, pPre + length - 1, pIn, pIn + length - 1);
		// 释放堆上的内存,防止内存泄漏,并清空指针
		delete[] pPre;
		pPre = NULL;
		delete[] pIn;
		pIn = NULL;
		return root;
	}
private:
	TreeNode* ConstructCore(long* pPreStart, long* pPreEnd, long* pInStart, long* pInEnd){
		// 构建根节点
		long rootValue = *(long*)pPreStart[0];
		TreeNode* root = new TreeNode(rootValue);
		root->left = root->right = NULL;

		// 判断是否为递归的退出条件:前序是否到头、中序是否到头、前序与中序是否重合
		if (pPreStart == pPreEnd || pInStart == pInEnd || pPreStart == pInStart){
			return root;
		}

		// 在中序数组中找到根节点的位置
		long* rootPosi = pInStart;
		while (rootPosi <= pInEnd && *(long*)rootPosi[0] != rootValue){
			rootPosi++;
		}
		// 检验是否在中序数组中找到根节点
		if (rootPosi == pInEnd && *(long*)rootPosi[0] != rootValue){ 
			// *(long*)rootPosi与*(long*)rootPosi[0]意义完全不同,*(long*)rootPosi是把数组的第一个元素到最后一个元素看成整体解除指针引用
			//throw new exception("not found!");
			return NULL;
		}

		// 中序数组中根节点据数组头部的距离
		long leftLength = rootPosi - pInStart;

		// 构建左子树的四个实参
		long* pNewPreStartLeft = pPreStart + 1;
		long* pNewPreEndLeft = pPreStart + leftLength;
		long* pNewInStartLeft = pInStart;
		long* pNewInEndLeft = pInStart + leftLength - 1;

		// 构建右子树的四个实参
		long* pNewPreStartRight = pPreStart + leftLength + 1;
		long* pNewPreEndRight = pPreEnd;
		long* pNewInStartRight = rootPosi + 1;
		long* pNewInEndRigth = pInEnd;
		if (leftLength > 0){
			root->left = ConstructCore(pNewPreStartLeft, pNewPreEndLeft, pNewInStartLeft, pNewInEndLeft);
		}
		if (leftLength < pPreEnd - pPreStart){
			root->right = ConstructCore(pNewPreStartRight, pNewPreEndRight, pNewInStartRight, pNewInEndRigth);
		}
		return root;
	}
};
int _tmain(int argc, _TCHAR* argv[])
{
	int arrPre[] = { 1, 2, 4, 7, 3, 5, 6, 8 };
	int arrIn[] = { 4, 7, 2, 1, 5, 3, 8, 6 };
	vector<int> pre(arrPre, arrPre + 8);
	vector<int> in(arrIn, arrIn + 8);

	Solution s;
	TreeNode* result = s.reConstructBinaryTree(pre, in);
	system("pause");
	return 0;
}


 
   

你可能感兴趣的:(4.重建二叉树)