二叉树 | 遍历 (链表实现)

2019-07-29  本文已影响0人  zilla

遍历

二叉树的遍历即通过一定顺序访问二叉树的所有结点。

前三种通常递归实现(DFS),层次遍历通过BFS实现。
先、中、后指:根结点在遍历中的位置。
无论递归遍历中哪一种,左子树一定先于右子树遍历。

递归遍历

void xxxxOrder(Node *root) {
    // 递归边界
    if(root == NULL) return;
    // 先序:访问根结点root……
    // 递归左、右子树
    xxxxOrder(root->lchild);
    // 中序:访问根结点root……
    xxxxOrder(root->rchild);
    // 后序:访问根结点root……
}

根据中序、先序/后序/层序遍历还原二叉树(递归)

(所有元素不相同时)

层序遍历

二叉树的广度正体现在层次上,BFS搜索即可(用queue实现)。
若需要计算每个结点的层次,在struct Node中加int layer字段。

#include <cstdio>
#include <queue>

using namespace std;
int nn, in_order[32], post_order[32];
struct Node {
    int data;
    Node *lchild, *rchild;
};

Node *create(int in_st, int in_ed, int post_st, int post_ed) {
    if (in_st > in_ed || post_st > post_ed)
        return NULL;
    int root_data = post_order[post_ed];
    int root_pos = -1;
    for (int i = in_st; i <= in_ed; ++i) {
        if (in_order[i] == root_data) {
            root_pos = i;
            break;
        }
    }
    int ltree_size = root_pos - in_st;
    /*
     * 注意:
     *   1    新结点Node* root = new Node 分配空间
     *   2    将递归调用返回的Node* 赋给root->lchild, root->rchild
     *         才能把树连起来!!!
     */
    Node *root = new Node;
    root->data = root_data;
    root->lchild = create(in_st, root_pos - 1, post_st, post_st + ltree_size - 1);
    root->rchild = create(root_pos + 1, in_ed, post_st + ltree_size, post_ed - 1);
    return root;
}

void BFS(Node *root) {
    int cnt = 0;
    queue<Node *> mq;
    mq.push(root);
    while (!mq.empty()) {
        Node *curr = mq.front();
        mq.pop();
        printf("%d", curr->data);
        cnt++;
        if (cnt < nn) printf(" ");
        if (curr->lchild != NULL) {
            mq.push(curr->lchild);
        }
        if (curr->rchild != NULL) {
            mq.push(curr->rchild);
        }
    }
}

int main() {
    scanf("%d", &nn);
    for (int i = 0; i < nn; ++i)
        scanf("%d", &post_order[i]);
    for (int i = 0; i < nn; ++i)
        scanf("%d", &in_order[i]);
    Node *root = create(0, nn - 1, 0, nn - 1);
    BFS(root);
    return 0;
}
#include <cstdio>
#include <stack>
#include <cstring>

using namespace std;
struct Node {
    int data;
    Node *lchild, *rchild;
};
int nn, in_order[32], pre_order[32];

Node *create_btree(int in_st, int in_ed, int pre_st, int pre_ed) {
    if (in_st > in_ed || pre_st > pre_ed)
        return NULL;
    Node *root = new Node;
    int root_data;
    root_data = root->data = pre_order[pre_st];
    int div = -1;
    for (int i = in_st; i <= in_ed; ++i) {
        if (in_order[i] == root_data) {
            div = i;
            break;
        }
    }
    int rchild_size = in_ed - div;
    root->lchild = create_btree(in_st, div - 1, pre_st + 1, pre_ed - rchild_size);
    root->rchild = create_btree(div + 1, in_ed, pre_ed - rchild_size + 1, pre_ed);
    return root;
}

void post_order_traverse(Node *root) {
    if (root == NULL) return;
    if (root->lchild != NULL) {
        post_order_traverse(root->lchild);
    }
    if (root->rchild != NULL) {
        post_order_traverse(root->rchild);
    }
    printf("%d", root->data);
    if (--nn) printf(" ");
}

int main() {
    stack<int> seq;
    int curr, ii = 0, pi = 0;
    scanf("%d", &nn);
    char op[5];
    for (int i = 0; i < 2 * nn; ++i) {
        scanf("%s", op);
        if (strlen(op) == 4) {
            scanf("%d", &curr);
            seq.push(curr);
            pre_order[pi] = curr;
            pi++;
        } else {
            in_order[ii] = seq.top();
            seq.pop();
            ii++;
        }
    }
    Node *root = create_btree(0, nn - 1, 0, nn - 1);
    post_order_traverse(root);
    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读