持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情
一、题目
描述:
给定节点数为n的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。
#include<iostream>
#include<vector>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
inline TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
TreeNode* makeTree(vector<int> pre,vector<int> vin) {
}
int main(int, char*[])
{
vector<int> pre = {1, 2, 4, 7, 3, 5 ,6, 8};
vector<int> vin = {4, 7, 2, 1, 5, 3, 8, 6};
TreeNode* root = makeTree(pre, vin);
cout << root->val << ' ';
cout << root->left->val << ' ';
cout << root->left->left->val << ' ';
cout << root->left->left->right->val << ' ';
cout << root->right->val << ' ';
cout << root->right->left->val << ' ';
cout << root->right->right->val << ' ';
cout << root->right->right->left->val << endl;
cout << "1 2 4 7 3 5 6 8" << endl;
}
二、分析
这道题考验对二叉树前序、中序、后序遍历的熟悉程度,实在比较陌生的话,就只能使用最原始最暴力的方法,找规律......
中序遍历的顺序是左根右,从这个顺序来看,从中序遍历的结果中找到根节点,左边的就肯定是左子树,右边的就肯定是右子树。
前序遍历的顺序是根左右,从这个顺序来看,可以很容易得到每个子树的根节点,配合中序遍历,就可以去中序遍历结果中去找到根节点,然后左边左子树,右边右子树这样进行子树的划分。
通过循环,不断的划分子树,直至为空。
三、模拟
- 1 -> 左:2,4,7 右:3,5,6,8
- 2 -> 左:4,7 右:空
- 4 -> 左:空 右:7
- 7 -> 左:空 右:空
- 3 -> 左:5 右:6,8
- 5 -> 左:空 右:空
- 6 -> 左:8 右:空
- 8 -> 左:空 右:空
四、实现
TreeNode* makeTreeDfs(vector<int>& pre,vector<int>& vin, int preStart, int preEnd, int vinStart, int vinEnd) {
if(preStart > preEnd) return nullptr;
TreeNode* root = new TreeNode(pre[preStart]);
int cur = vinStart;
while(root->val != vin[cur]) ++cur;
cur -= vinStart;
root->left = makeTreeDfs(pre, vin, preStart + 1, cur + preStart, vinStart, cur + vinStart - 1);
root->right = makeTreeDfs(pre, vin, cur + preStart + 1, preEnd, cur + vinStart + 1, vinEnd);
return root;
}
TreeNode* makeTree(vector<int> pre,vector<int> vin) {
if(pre.empty()) return nullptr;
return makeTreeDfs(pre, vin, 0, pre.size() - 1, 0, vin.size() - 1);
}
五、结言
掌握基础算法,遇事儿咱不慌。
创作不易,留个赞再走吧!如果对文章内容有任何指正,欢迎评论!