zoukankan      html  css  js  c++  java
  • 遍历二叉树:前序、中续、后续、递归、非递归

    树节点定义:

    struct Node {
        int data; 
        Node *left; 
        Node *right; 
    };

    递归实现:

    void visit(Node *node) {
        assert(node != NULL);
        printf("%d ", node->data);
    }
    
    void visitPrevOrderRec(Node *tree) {
        if (tree == NULL) return ;
        visit(tree);
        visitPrevOrderRec(tree->left);
        visitPrevOrderRec(tree->right);
    }
    
    void visitMidOrderRec(Node *tree) {
        if (tree == NULL) return ;
        visitMidOrderRec(tree->left);
        visit(tree); 
        visitMidOrderRec(tree->right); 
    }
    
    void visitPostOrderRec(Node *tree) {
        if (tree == NULL) return ;
        visitPostOrderRec(tree->left);
        visitPostOrderRec(tree->right);
        visit(tree); 
    } 

    简单直接的非递归实现:

    enum _travel_type{
        VISIT, 
        TRAVEL, 
    }; 
    
    typedef pair<enum _travel_type, Node *> NodeTravel;
    
    void visitPrevOrderSimple(Node *tree) {
        stack<Node *> stack;
        if (tree == NULL) return ;
        
        stack.push(tree);
        while (!stack.empty()) {
            Node *cur = stack.top(); 
            stack.pop();
            visit(cur);
            if (cur->right != NULL) stack.push(cur->right);
            if (cur->left != NULL) stack.push(cur->left);
        }
    } 
    
    void visitMidOrderSimple(Node *tree) {
        stack<NodeTravel> stack;
        if (tree == NULL) return ;
        stack.push(NodeTravel(TRAVEL, tree));
        while (!stack.empty()){
            NodeTravel t = stack.top(); 
            stack.pop(); 
            Node *cur = t.second; 
            if (t.first == VISIT) {
                visit(cur);
            } else {
                if (cur->right) stack.push(NodeTravel(TRAVEL, cur->right));
                stack.push(NodeTravel(VISIT, cur));
                if (cur->left) stack.push(NodeTravel(TRAVEL, cur->left));
            }
        }
    }
    
    void visitPostOrderSimple(Node *tree) {
        stack<NodeTravel> stack;
        if (tree == NULL) return ;
        stack.push(NodeTravel(TRAVEL, tree)); 
        while (!stack.empty()) {
            NodeTravel t = stack.top();
            stack.pop(); 
            Node *cur = t.second; 
            if (t.first == VISIT) {
                visit(cur); 
            } else {
                stack.push(NodeTravel(VISIT, cur));
                if (cur->right != NULL) 
                    stack.push(NodeTravel(TRAVEL, cur->right));
                if (cur->left != NULL)
                    stack.push(NodeTravel(TRAVEL, cur->left));
            }
        }
    } 

    对于中续和后续遍历,还有更好的方法(不需要借助pair):

    void visitMidOrder(Node *tree) {
        stack<Node *> stack;
        while (tree != NULL || !stack.empty()) {
            while (tree != NULL) {
                stack.push(tree); 
                tree = tree->left;
            }
            
            if (!stack.empty()) {
                Node *n = stack.top();
                stack.pop(); 
                visit(n); 
                tree = n->right; 
            }
        }
    } 
    
    void visitPostOrder(Node *tree) {
        stack<Node *> stack;
        if (tree == NULL) return ;
        stack.push(tree); 
        Node *pp = NULL; 
        
        while (!stack.empty()) {
            Node *cur = stack.top(); 
            Node *last = cur->right; 
            if (last == NULL) last = cur->left; 
            if (last == NULL || last == pp) {
                visit(cur);
                pp = cur; 
                stack.pop(); 
            } // last != NULL && last != pp
            else if (cur->left == NULL || cur->left == pp) {
                stack.push(cur->right);
            } else {
                stack.push(cur->left);
            }
        }
    } 

    发现任何错误或者有更好的方法,欢迎回复!

  • 相关阅读:
    【BZOJ4367】[IOI2014]holiday假期 分治+主席树
    【BZOJ1264】[AHOI2006]基因匹配Match DP+树状数组
    【BZOJ4379】[POI2015]Modernizacja autostrady 树形DP
    【BZOJ4380】[POI2015]Myjnie 区间DP
    【BZOJ4382】[POI2015]Podział naszyjnika 堆+并查集+树状数组
    【BZOJ4384】[POI2015]Trzy wieże 树状数组
    【BZOJ4388】JOI2012 invitation 堆+线段树+并查集(模拟Prim)
    【BZOJ4550】小奇的博弈 博弈论
    Sqlserver列出所有数据库名,表名,字段名
    聚合与组合的区别?
  • 原文地址:https://www.cnblogs.com/isaiah/p/2733281.html
Copyright © 2011-2022 走看看