给定前序遍历序列和中序遍历序列,恢复出二叉树。前序序列{1,2,4,7,3,5,6,8},中序序列{4,7,2,1,5,3,8,6}
其复原思想:
利用递归思想,
前序找根结点,利用中序确定左子树结点个数和右子树的结点个数。
接着从前序中分别递归到左右子树中去重建二叉树。
递归的结束条件只剩一个结点且前序和中序所指向的是同一结点。
代码见下:
#include<iostream>
#include<vector>
using namespace std;
struct TreeNode {
int val;
TreeNode* left, *right;
TreeNode(int x):val(x),right(nullptr),left(nullptr){}
};
TreeNode* construct(vector<int>& preOrder, int pStart, int pEnd,
vector<int>& inOrder, int iStart, int iEnd) {
TreeNode* root = new TreeNode(preOrder[pStart]);
//设置递归终止条件
if (pStart == pEnd) {
if (iStart == iEnd&&preOrder[pStart] == inOrder[iStart])
return root;
}
//计算左子树节点的个数
int leftLen = 0;
for (int i = iStart; inOrder[i] != preOrder[pStart]; ++i)
++leftLen;
//分别递归左右子树,构建树。。。写以下序号参数的填写最好能图形结合
if (leftLen > 0)//判断左子树非空
root->left = construct(preOrder, pStart + 1, pStart + leftLen, inOrder, iStart, iStart + leftLen - 1);
if (leftLen < pEnd - pStart)//判断右子树非空
root->right = construct(preOrder, pStart + leftLen + 1, pEnd, inOrder, iStart + leftLen + 1, iEnd);
return root;
}
TreeNode* reBuildBinaryTree(vector<int>& preOrder, vector<int>& inOrder) {
if (preOrder.empty() || inOrder.empty() || preOrder.size() != inOrder.size())
return nullptr;
return construct(preOrder, 0, preOrder.size() - 1, inOrder, 0, inOrder.size() - 1);
}
//用来验证构建二叉树是否正确
void preOrder(TreeNode* root) {
if (root == nullptr) {
return;
}
cout << root->val << endl;
if (root->left)
preOrder(root->left);
if (root->right)
preOrder(root->right);
}
int main() {
vector<int> preO = { 1,2,4,7,3,5,6,8 };
vector<int> inO = { 4,7,2,1,5,3,8,6 };
TreeNode* root = reBuildBinaryTree(preO, inO);
preOrder(root);
return 0;
}