遍历二叉树:前序、中续、后续、递归、非递归

树节点定义:

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);
        }
    }
} 

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

 

 

posted @ 2012-10-22 08:04  lorddeseis  阅读(618)  评论(0编辑  收藏  举报