构建二叉树

构建二叉树

本文图文并茂讲解从前序遍历、中序续遍历构建二叉树或者从后序遍历、中序续遍历又或者从前序遍历、后序续遍历构建二叉树的原理,比附上相关的习题。

注意:

将提供以下图文链接供大家理解:

图文链接:
飞书图解链接🎉🎉🎉
密码:86N2619&

1. 从前序遍历、中序续遍历构建二叉树

题目一

LeetCode 105. 从前序与中序遍历序列构造二叉树

AC代码,展开查看
/**
 * 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:
    unordered_map<int, int> pos;
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        for(int i = 0; i < inorder.size(); i ++ ) pos[inorder[i]] = i;
        return build(preorder, inorder, 0, preorder.size() - 1, 0, inorder.size() - 1);
    }
    TreeNode* build(vector<int>& preorder, vector<int>& inorder, int pl, int pr, int il, int ir){
        if(pl > pr) return nullptr;
        auto root = new TreeNode(preorder[pl]);
        int k = pos[root -> val];
        root -> left = build(preorder, inorder, pl + 1, k - il + pl, il, k - 1);
        root -> right = build(preorder, inorder, k - il + pl + 1, pr, k + 1, ir);
        return root;
    }
};

2. 从后序遍历、中序续遍历构建二叉树

题目一

LeetCode 106. 从中序与后序遍历序列构造二叉树

AC代码,展开查看
/**
 * 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:
    unordered_map<int, int> pos;
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        for(int i = 0; i < inorder.size(); i ++ ) pos[inorder[i]] = i;
        return build(inorder, postorder, 0, inorder.size() - 1, 0, postorder.size() - 1);
    }
    TreeNode* build(vector<int>& inorder, vector<int>& postorder, int il, int ir, int pl, int pr){
        if(il > ir) return nullptr;
        auto root = new TreeNode(postorder[pr]);
        int k = pos[root -> val];
        root -> left = build(inorder, postorder, il, k - 1, pl, pl + k - il - 1);
        root -> right = build(inorder, postorder, k + 1, ir, pl + k - il, pr - 1);
        return root;
    }
};

题目二

前置知识

  1. 数组模拟二叉树
    • 数组大小为: 将此二叉树转化为完全二叉树的节点的数目 + 1
    • 注意: 节点必须从索引1开始

示例代码:

AC代码,展开查看
#include<bits/stdc++.h>
using namespace std;
const int N = 9;
int a[N]; // 根节点在a[1]
void proOrder(int index){
    if(index > N) return;
    cout << a[index] << endl;
    proOrder(2 * index);
    proOrder(2 * index + 1);
}
int main(){
    for(int i = 1; i <= N; i ++ ) a[i] = i;
    proOrder(1);
    return 0;
}
/*
运行结果
1
2
4
8
9
5
3
6
7
*/
  1. 结构体二叉树

示例代码:

AC代码,展开查看
#include<bits/stdc++.h>
using namespace std;
const int N = 9;
struct Node{
    int val;
    Node* left;
    Node* right;
    Node(int val){
        this -> val = val;
    }
    ~Node(){
        cout << "回收掉的val值为: " << this -> val << "\n";
    }
};
Node* buildTree(int val){
    if(val > N) return nullptr;
    Node* root = new Node(val);
    root -> left = buildTree(2 * val);
    root -> right = buildTree(2 * val + 1);
    return root;
}
void proOrder(Node* root){
    if(!root) return;
    cout << "前序: " << root -> val << "\n";
    proOrder(root -> left);
    proOrder(root -> right);
}
void inOrder(Node* root){
    if(!root) return;
    inOrder(root -> left);
    cout << "中序: " << root -> val << "\n";
    inOrder(root -> right);
}
void postOrder(Node* root){
    if(!root) return;
    postOrder(root -> left);
    postOrder(root -> right);
    delete root;
}
int main(){
    auto root = buildTree(1);
    proOrder(root);
    inOrder(root);
    postOrder(root);
    return 0;
}
/*
运行结果
1
2
4
8
9
5
3
6
7
*/

洛谷 P1030 [NOIP2001 普及组] 求先序排列

解题思路:

  1. 根据后序遍历和中序遍历构建出二叉树,然后进行一次前序遍历
AC代码,展开查看
#include<bits/stdc++.h>
using namespace std;
const int N = 10; // 长度小于等于8
unordered_map<char, int> pos;
struct Node{
    char val;
    Node* left;
    Node* right;
    Node(int val){
        this -> val = val;
    }
    ~Node(){
        cout << "回收掉的val值为: " << this -> val << "\n";
    }
};
Node* build(string& inorder, string& postorder, int il, int ir, int pl, int pr);
Node* buildTree(string& inorder, string& postorder) {
    for(int i = 0; i < inorder.size(); i ++ ) pos[inorder[i]] = i;
    return build(inorder, postorder, 0, inorder.size() - 1, 0, postorder.size() - 1);
}
Node* build(string& inorder, string& postorder, int il, int ir, int pl, int pr){
    if(il > ir) return nullptr;
    auto root = new Node(postorder[pr]);
    int k = pos[root -> val];
    root -> left = build(inorder, postorder, il, k - 1, pl, pl + k - il - 1);
    root -> right = build(inorder, postorder, k + 1, ir, pl + k - il, pr - 1);
    return root;
}
void proOrder(Node* root){
    if(!root) return;
    cout << root -> val;
    proOrder(root -> left);
    proOrder(root -> right);
}
void postOrder(Node* root){
    if(!root) return;
    postOrder(root -> left);
    postOrder(root -> right);
    delete root;
}
int main(){
    string inStr, postStr;
    cin >> inStr >> postStr;
    auto root = buildTree(inStr, postStr);
    proOrder(root);
    postOrder(root);
    return 0;
}
  1. 根据后序遍历和中序遍历输出前序遍历
AC代码,展开查看
#include<bits/stdc++.h>
using namespace std;
const int N = 10;
//   中序       后序
char inStr[N], postStr[N];
unordered_map<char, int> pos;
 
void dfs(char inStr[], char postStr[], int il, int ir, int pl, int pr){
    if(ir >= il){
        char c = postStr[pr]; // 根节点, 按序输出根节点即为前序遍历
        printf("%c", c);
        int k = pos[c];
        dfs(inStr, postStr, il, k - 1, pl, k - il - 1 + pl);
        dfs(inStr, postStr, k + 1, ir, k - il + pl, pr - 1);
    }
}
 
int main(){
    scanf("%s%s", inStr, postStr);
    int n = strlen(inStr);
    for(int i = 0; i < n; i ++ ) pos[inStr[i]] = i;
    dfs(inStr, postStr, 0, n - 1, 0, n - 1);
    return 0;
}

3. 从前序遍历、后序续遍历构建二叉树

题目一

LeetCode 889. 根据前序和后序遍历构造二叉树

AC代码,展开查看
/**
 * 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:
    unordered_map<int, int> pos;
    TreeNode* constructFromPrePost(vector<int>& preorder, vector<int>& postorder) {
        for(int i = 0; i < postorder.size(); i ++ ) pos[postorder[i]] = i;
        return build(preorder, postorder, 0, preorder.size() - 1, 0, postorder.size() - 1);
    }
    // postorder -> afterorder
    TreeNode* build(vector<int>& preorder, vector<int>& postorder, int pl, int pr, int al, int ar){
        if(pl > pr) return nullptr;
        auto root = new TreeNode(preorder[pl]);
        if(pl == pr) return root;
        int k = pos[preorder[pl + 1]];
        root -> left = build(preorder, postorder, pl + 1, k - al + pl + 1, al, k);
        root -> right = build(preorder, postorder, k - al + pl + 2, pr, k + 1, ar);
        return root;
    }
};

海纳百川,有容乃大!如果文章有什么不足之处,还请大神们评论区留言指出,我在此表达感谢🥰!若大家喜欢我的作品,欢迎点赞、收藏、打赏🎉🎉🎉!

posted @ 2023-11-18 23:25  爱情丶眨眼而去  阅读(12)  评论(0编辑  收藏  举报