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

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

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

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

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

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

  先序遍历:  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 @ 2020-11-30 16:21  dreamy-xay  阅读(782)  评论(0)    收藏  举报