zoukankan      html  css  js  c++  java
  • 二叉树前中后序遍历递归转循环

    通过观察递归实现,用循环和栈模拟递归实现中结点入栈和出栈的过程。

    #include <bits/stdc++.h>
    #define DBG(x) cerr << #x << " = " << x << endl
    
    using namespace std;
    typedef long long LL;
    
    struct Node {
        int val;
        Node *left, *right;
    
        Node() : left(NULL), right(NULL) {}
    
        Node(int val) : val(val), left(NULL), right(NULL) {}
    };
    
    enum StackState {
        AFTER_PUSH_ROOT = 0,
        AFTER_PUSH_LEFT = 1,
        AFTER_PUSH_RIGHT = 2,
    };
    
    void dfs_pre_order(Node *root, vector<int> &ret) {
        ret.push_back(root->val);
        if (root->left) dfs_pre_order(root->left, ret);
        if (root->right) dfs_pre_order(root->right, ret);
    }
    
    void dfs_in_order(Node *root, vector<int> &ret) {
        if (root->left) dfs_in_order(root->left, ret);
        ret.push_back(root->val);
        if (root->right) dfs_in_order(root->right, ret);
    }
    
    void dfs_post_order(Node *root, vector<int> &ret) {
        if (root->left) dfs_post_order(root->left, ret);
        if (root->right) dfs_post_order(root->right, ret);
        ret.push_back(root->val);
    }
    
    void pre_order(Node *root, vector<int> &ret) {
        stack<pair<Node *, StackState>> stk;
        stk.push(pair<Node *, StackState>(root, AFTER_PUSH_ROOT));
        while (!stk.empty()) {
            pair<Node *, StackState> &top = stk.top();
            switch (top.second) {
                case AFTER_PUSH_ROOT:
                    ret.push_back(top.first->val);
                    if (top.first->left) stk.push(pair<Node *, StackState>(top.first->left, AFTER_PUSH_ROOT));
                    top.second = AFTER_PUSH_LEFT;
                    break;
                case AFTER_PUSH_LEFT:
                    if (top.first->right) stk.push(pair<Node *, StackState>(top.first->right, AFTER_PUSH_ROOT));
                    top.second = AFTER_PUSH_RIGHT;
                    break;
                case AFTER_PUSH_RIGHT:
                    stk.pop();
                    break;
            }
        }
    }
    
    void in_order(Node *root, vector<int> &ret) {
        stack<pair<Node *, StackState>> stk;
        stk.push(pair<Node *, StackState>(root, AFTER_PUSH_ROOT));
        while (!stk.empty()) {
            pair<Node *, StackState> &top = stk.top();
            switch (top.second) {
                case AFTER_PUSH_ROOT:
                    if (top.first->left) stk.push(pair<Node *, StackState>(top.first->left, AFTER_PUSH_ROOT));
                    top.second = AFTER_PUSH_LEFT;
                    break;
                case AFTER_PUSH_LEFT:
                    ret.push_back(top.first->val);
                    if (top.first->right) stk.push(pair<Node *, StackState>(top.first->right, AFTER_PUSH_ROOT));
                    top.second = AFTER_PUSH_RIGHT;
                    break;
                case AFTER_PUSH_RIGHT:
                    stk.pop();
                    break;
            }
        }
    }
    
    void post_order(Node *root, vector<int> &ret) {
        stack<pair<Node *, StackState>> stk;
        stk.push(pair<Node *, StackState>(root, AFTER_PUSH_ROOT));
        while (!stk.empty()) {
            pair<Node *, StackState> &top = stk.top();
            switch (top.second) {
                case AFTER_PUSH_ROOT:
                    if (top.first->left) stk.push(pair<Node *, StackState>(top.first->left, AFTER_PUSH_ROOT));
                    top.second = AFTER_PUSH_LEFT;
                    break;
                case AFTER_PUSH_LEFT:
                    if (top.first->right) stk.push(pair<Node *, StackState>(top.first->right, AFTER_PUSH_ROOT));
                    top.second = AFTER_PUSH_RIGHT;
                    break;
                case AFTER_PUSH_RIGHT:
                    ret.push_back(top.first->val);
                    stk.pop();
                    break;
            }
        }
    }
    
    Node *get_tree(int num) {
        Node *root = new Node(random());
        vector<Node *> nodes;
        nodes.push_back(root);
    
        for (int i = 0; i < num; i++) {
            unsigned int pos = random() * random() * random() % nodes.size();
            if (nodes[pos]->left == NULL && nodes[pos]->right == NULL) {
                if (random() % 2 == 0) {
                    nodes[pos]->left = new Node(random());
                    nodes.push_back(nodes[pos]->left);
                } else {
                    nodes[pos]->right = new Node(random());
                    nodes.push_back(nodes[pos]->right);
                }
            } else if (nodes[pos]->left) {
                nodes[pos]->right = new Node(random());
                nodes.push_back(nodes[pos]->right);
            } else {
                nodes[pos]->left = new Node(random());
                nodes.push_back(nodes[pos]->left);
            }
            if (nodes[pos]->left && nodes[pos]->right) {
                nodes.erase(nodes.begin() + pos);
            }
        }
    
        return root;
    }
    
    void free_tree(Node *root) {
        if (root->left) free_tree(root->left);
        if (root->right) free_tree(root->right);
        delete root;
    }
    
    void test_pre_order() {
        Node *tree = get_tree(100000);
        vector<int> dfs_ret, ret;
    
        dfs_pre_order(tree, dfs_ret);
        pre_order(tree, ret);
        assert(dfs_ret == ret);
    
        free_tree(tree);
    }
    
    void test_in_order() {
        Node *tree = get_tree(100000);
        vector<int> dfs_ret, ret;
    
        dfs_in_order(tree, dfs_ret);
        in_order(tree, ret);
        assert(dfs_ret == ret);
    
        free_tree(tree);
    }
    
    void test_post_order() {
        Node *tree = get_tree(100000);
        vector<int> dfs_ret, ret;
    
        dfs_post_order(tree, dfs_ret);
        post_order(tree, ret);
        assert(dfs_ret == ret);
    
        free_tree(tree);
    }
    
    int main(int argc, char **argv) {
        srand(time(NULL));
    
        test_pre_order();
        test_in_order();
        test_post_order();
    
        return 0;
    }
    
  • 相关阅读:
    跨媒体安全
    kali视频(21-25)学习
    kali视频(26-30)学习
    kali视频(16-20)学习
    kali视频学习(11-15)
    kali视频(1-5)
    使用Metaspoit攻击MS08-067
    web应用程序安全攻防---sql注入和xss跨站脚本攻击
    -区块链-
    TCP/IP网络协议攻击
  • 原文地址:https://www.cnblogs.com/ToRapture/p/12115657.html
Copyright © 2011-2022 走看看