恢復二叉樹(先序+中序)

  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;
}
相關文章
相關標籤/搜索