和从中序与后序遍历序列构造二叉树类似
对于任意一颗树:
根节点总是前序遍历中的第一个节点,前序遍历的形式总是:
[ 根节点, [左子树的中序遍历结果], [右子树的中序遍历结果]]
中序遍历的形式总是:
[ [左子树的中序遍历结果], 根节点, [右子树的中序遍历结果] ]
已知
1: 前序遍历的第一个一定是根节点。
2: 中序遍历能区分出左右子树。
3: 中序遍历和后序遍历的左右子树的长度一定是相等。
那么
从前序遍历中得到根结点,将中序遍历中的左右子树分割开,用得到的左右子树的长度再将前序遍历中的左右子树分割开,再从其中找根结点。
具体步骤
1:如果数组大小为零的话,说明是空节点。
2:如果不为空,那么取后序数组最后一个元素作为节点元素。
3:找到前序数组最后一个元素在中序数组的位置,作为切割点
4:切割中序数组,切成中序左数组和中序右数组
5:切割前序数组,切成前序左数组和前序右数组
6:递归处理左区间和右区间
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size() == 0 || inorder.size() == 0)
return NULL;
return traversal(preorder, inorder);
}
TreeNode* traversal(vector<int>& preorder, vector<int>& inorder){
if(preorder.size() == 0)
return NULL;
int rootValue = preorder[0];
TreeNode* root = new TreeNode(rootValue);
if(preorder.size() == 1)
return root;
int delimiter;
for(delimiter = 0; delimiter < inorder.size(); delimiter++){
if(inorder[delimiter] == rootValue)
break;
}
//cut
//inorder
vector<int> leftInorder(inorder.begin(), inorder.begin() + delimiter);
vector<int> rightInorder(inorder.begin() + delimiter + 1, inorder.end());
//preorder
vector<int> leftPreorder(preorder.begin() + 1, preorder.begin() + 1 + leftInorder.size());
vector<int> rightPreorder(preorder.begin() + 1 + leftInorder.size(), preorder.end());
root->left = traversal(leftPreorder, leftInorder);
root->right = traversal(rightPreorder, rightInorder);
return root;
}
};