花の咲季節花开的季节

根据后序遍历(先序遍历)和中序遍历建树

Dreamy·2020-11-30 16:21·744 次阅读

根据后序遍历(先序遍历)和中序遍历建树

    今天来总结下二叉树前序、中序、后序遍历相互求法,即如果知道两个的遍历,如何求第三种遍历方法,比较笨的方法是画出来二叉树,然后根据各种遍历不同的特性来求,也可以编程求出。

首先: 我们看看先序、中序、后序遍历的特性

  先序遍历: 
          ① 访问节点 
          ② 遍历左子树 
          ③ 遍历右子树 
  中序遍历: 
          ① 遍历左子树 
          ② 访问节点 
          ③ 遍历右子树 
  后序遍历: 
          ① 遍历左子树 
          ② 遍历右子树 
          ③ 访问节点

  对比三种遍历算法:只是访问顺序不同

分析:已知先序、中序遍历,求后序遍历

  先序遍历:  GDAFEMHZ

  中序遍历: ADEFGHMZ

 

🔥 根据前序遍历的特点,我们知道根结点为G

🔥 观察中序遍历ADEFGHMZ。其中root节点G左侧的ADEF必然是root的左子树,G右侧的HMZ必然是root的右子树。

🔥 观察左子树ADEF,左子树的中的根节点必然是大树的rootleftchild。在前序遍历中,大树的rootleftchild位于root之后,所以左子树的根节点为D

🔥 同样的道理,root的右子树节点HMZ中的根节点也可以通过前序遍历求得。在前序遍历中,一定是先把rootroot的所有左子树节点遍历完之后才会遍历右子树,并且遍历的左子树的第一个节点就是左子树的根节点。同理,遍历的右子树的第一个节点就是右子树的根节点。

🔥 观察发现,上面的过程是递归的。先找到当前树的根节点,然后划分为左子树,右子树,然后进入左子树重复上面的过程,然后进入右子树重复上面的过程。最后就可以还原一棵树了。该步递归的过程可以简洁表达如下:

    ① 确定根,确定左子树,确定右子树

    ② 在左子树中递归

    ③ 在右子树中递归

 

代码:以下是建树代码实现并遍历

 

🍀  后序和中序

#include <bits/stdc++.h>

using namespace std;

typedef struct TreeNode {
    int data;
    struct TreeNode *left, *right;
} TreeNode;

int post[100], in[100];

/*
input
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

output
4 1 6 3 5 7 2
*/

TreeNode* buildTree(int root, int start, int end) {
    if (start > end)
        return NULL;
    int i = end;
    while (i > start && in[i] != post[root]) i--;
    TreeNode* t = new TreeNode();
    t->data = post[root];
    t->left = buildTree(root - 1 + i - end, start, i - 1);
    t->right = buildTree(root - 1, i + 1, end);
    return t;
}

void bfs(TreeNode* T) {
    queue<TreeNode> qu;
    qu.push(*T);
    TreeNode p;
    int first = 1;
    while (!qu.empty()) {
        p = qu.front();
        qu.pop();
        if (first) {
            printf("%d", p.data);
            first = 0;
        } else
            printf(" %d", p.data);
        if (p.left)
            qu.push(*(p.left));
        if (p.right)
            qu.push(*(p.right));
    }
}

int main() {
    int N;
    cin >> N;
    for (int i = 0; i < N; i++)
        cin >> post[i];
    for (int i = 0; i < N; i++)
        cin >> in[i];
    TreeNode* tree = buildTree(N - 1, 0, N - 1);
    bfs(tree);
    putchar(10);
    system("pause");
    return 0;
}

 

 

🍀  先序和中序(和后序同理

#include <bits/stdc++.h>

using namespace std;

typedef struct TreeNode {
    int data;
    struct TreeNode *left, *right;
} TreeNode;

int pre[100], in[100];

/*
input
6
1 2 3 4 5 6
3 2 4 1 6 5

output
1 2 5 3 4 6
*/

TreeNode* buildTree(int root, int start, int end) {
    if (start > end)
        return NULL;
    int i = start;
    while (i < end && in[i] != pre[root]) i++;
    TreeNode* t = new TreeNode();
    t->data = pre[root];
    t->left = buildTree(root + 1, start, i - 1);
    t->right = buildTree(root + 1 + i - start, i + 1, end);
    return t;
}

void bfs(TreeNode* T) {
    queue<TreeNode> qu;
    qu.push(*T);
    TreeNode p;
    int first = 1;
    while (!qu.empty()) {
        p = qu.front();
        qu.pop();
        if (first) {
            printf("%d", p.data);
            first = 0;
        } else
            printf(" %d", p.data);
        if (p.left)
            qu.push(*(p.left));
        if (p.right)
            qu.push(*(p.right));
    }
}

int main() {
    int N;
    cin >> N;
    for (int i = 0; i < N; i++)
        cin >> pre[i];
    for (int i = 0; i < N; i++)
        cin >> in[i];
    TreeNode* tree = buildTree(0, 0, N - 1);
    bfs(tree);
    putchar(10);
    system("pause");
    return 0;
}

 

posted @   dreamy-xay  阅读(744)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示