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;
    }
    
  • 相关阅读:
    018_STM32程序移植之_串口接收中文
    003_软件安装之_Visual Studio 2012
    001_C#我的第一个串口上位机软件
    017_STM32程序移植之_AS608指纹模块
    016_STM32程序移植之_舵机
    015_STM32程序移植之_NRF24L01模块
    014_STM32程序移植之_L298N电机驱动模块
    002_89C52_Proteus_DAC0832_输出50HZ,正弦波,三角波,矩形波,锯齿波
    001_89C52之_Proteus_ADC0809采集电压
    001_电子工程师招聘笔试题及详细解析
  • 原文地址:https://www.cnblogs.com/ToRapture/p/12115657.html
Copyright © 2011-2022 走看看