zoukankan      html  css  js  c++  java
  • 数据结构-二叉树(3)二叉树遍历的非递归算法

    不使用递归算法,想遍历二叉树:

    #include <istream>
    #include "stack.h"
    #include "queue.h"
    using namespace std;
    
    void BinaryTree<T>::PreOrder(void (*visit)(BinTreeNode<T> *p)){
    //  每次访问一个结点之后,用栈记录该结点的右子女,以便从左子女退回时可以直接从栈顶取得右子女的根结点,继续右子女的前序遍历
        stack<BinTreeNode<T>*> S;
        BinTreeNode<T> *p=root;
        S.Push(NULL);
        while(p!=NULL){
            visit(p);
            if(p->rightChild!=NULL) S.Push(p->rightChild);
            if(p->leftChild!=NULL) p=p->leftChild;
            else S.Pop(p);  //左子树为空
        }
    }
    
    template <class T>
    void BinaryTree<T>::PreOrder(void (*visit)(BinTreeNode<T> *p)){
    //  另一种前序遍历的方法。进栈时先进右子树结点地址,再进左子树;出栈时相反。
        stack<BinTreeNode<T>*> S;
        BinTreeNode<T> *p;
        S.Push(root);
        while (!S.IsEmpty()) {
            S.Pop(p);visit(p);
            if(p->rightChild!=NULL) S.Push(p->rightChild);
            if(p->leftChild!=NULL) S.Push(p->leftChild);
        }
    }
    
    template <class T>
    void BinTreeNode<T>::LevelOrder(void (*visit)(BinTreeNode<T> *p)){
    //  利用队列进行层次性遍历
        Queue<BinTreeNode<T>*> Q;
        BinTreeNode<T> *p=root;
        Q.EnQueue(p);
        while(!Q.IsEmpty()){
            Q.DeQueue(p);visit(p);
            if(p->leftChild!=NULL) Q.EnQueue(p->leftChild);
            if(p->rightChild!=NULL) Q.EnQueue(p->rightChild);
        }
    }
    
    template <class T>
    void BinaryTree<T>::InOrder(void (*visit)(BinTreeNode<T> *p)){
    // 利用栈进行中序遍历
        stack<BinTreeNode<T>*> S;
        BinTreeNode<T> *p=root;
        do{
            while(p!=NULL){
                S.Push(p);
                p=p->leftChild;
            }
            if(!S.IsEmpty()){
                S.Pop(p);visit(p);
                p=p->rightChild;
            }
        }while(p!=NULL || !S.IsEmpty());  //栈为空同时遍历指针也为空时结束循环
    }
    
    template <class T>
    struct stkNode{
    //  后序遍历时,必须借助栈结点结构,记录刚才是在左子树中还是右子树中
        BinTreeNode<T> *ptr;
        enum tag{L,R};
        stkNode(BinTreeNode<T> *N=NULL):ptr(N),tag(L){}
    }
    
    template <class T>
    void BinaryTree<T>::PostOrder(void (*visit)(BinTreeNode<T> *p)){
        Stack<stkNode<T>> S;
        stkNode<T> w;
        BinTreeNode<T> *p=root;
        do{
            while(p!=NULL){
                w.ptr=p;w.tag=L;S.Push(w);
                p=p->leftChild;
            }
            int continue1=1;    //继续循环标记,用于Case L情况结束小循环继续大循环。Case R情况继续小循环。
            while(continue1 && !S.IsEmpty()){
                S.Pop(w);p=w.ptr;
                switch(w.tag){
                    case L:w.tag=R;S.Push(w);
                           continue1=0;
                           p=p->rightChild;
                           break;
                    case R:visit(p);
                           break;
                }
            }
        }while(!S.IsEmpty());
        cout<<endl;
    }
  • 相关阅读:
    java开发异常类型汇总
    dm642在线写EPROM.txt
    [Codecademy] HTML&CSS 第一课:HTML Basic
    bram和dram差别
    Advanced Fruits HDU杭电1503【LCS的保存】
    add Admob with Cocos2d-x on iOS
    一种基于Qt的可伸缩的全异步C/S架构server实现(五) 单层无中心集群
    【SSH2框架(理论篇)】--SSH2 Vs 经典三层
    CSS BFC学习笔记
    【智能家居篇】wifi网络结构(上)
  • 原文地址:https://www.cnblogs.com/yangyuliufeng/p/9443776.html
Copyright © 2011-2022 走看看