恢复二叉树(先序+中序)

  1. 知道二叉树,能够对二叉树有4种遍历方式,分别为先序遍历,中序遍历,后序遍历以及层次遍历;那么知道(先序+中序)或者(后序+中序)怎样恢复这个二叉树呢?

算法思想
先根据先序序列的第一个元素创建根节点,而后在中序序列中查找该元素,依据该元素在中序序列中的位置,肯定根节点的左,右子树的中序序列;
再在先序序列中肯定左,右子树的先序序列;
最后由左子树的先序序列与中序序列创建左子树,由右子树的先序序列与中序序列创建右子树;
ios

#include<iostream>
#include<vector>
using namespace std;

struct TreeNode {
	char val;
	TreeNode* left;
	TreeNode* right;
};
TreeNode* recreateTree(vector<char> pre, vector<char> vin) {
	if (pre.size() == 0 && vin.size() == 0) {
		return NULL;
	}
	TreeNode* root = new TreeNode;
	int i, j;

	//在中序序列中找到先序第一个位置
	for (i = 0; i < vin.size(); i++) {
		if (vin[i] == pre[0]) break;
	}

	//将先序序列和中序序列分为 :左侧先序序列和中序序列 右侧先序序列和中序序列
	vector<char> lpre, lvin, rpre, rvin;
	for (j = 1; j <= i; j++) {
		lpre.push_back(pre[j]);
	}
	for (j = 0; j < i; j++) {
		lvin.push_back(pre[j]);
	}
	for (j = i + 1; j < pre.size(); j++) {
		rpre.push_back(pre[j]);
	}
	for (j = i + 1; j < vin.size(); j++) {
		rvin.push_back(vin[j]);
	}

	//递归生成root的左右子树
	root->left = recreateTree(lpre, lvin);
	root->right = recreateTree(rpre, rvin);
	return root;
}

void Visit(TreeNode* T) {
	cout << T->val << " ";
}
void PostOrder(TreeNode* T) {
	if (T != NULL) {
		PostOrder(T->left);
		PostOrder(T->right);
		Visit(T);
	}
}

int main() {
	TreeNode* root;

	vector<char> pre={'A','B','D','C','E','F'};
	vector<char> vin = { 'D','B','A','E','C','F' };
	root = recreateTree(pre, vin);
	PostOrder(root);
	return 0;
}