对二叉树以前序遍历、中序遍历、后序遍历三种方式递归及非递归的方式遍历树。


/**
 * 文件名:VisitTree.cpp
 * 功能:分别对二叉树以前、中、后三种方式递归及非递归的方式遍历树。
 * 作者:Neicole
 * 日期:2013.06.08
 * 联系:http://blog.csdn.net/neicole
 **/
#pragma once
#include <iostream>
#include <stack>
using std::cout;
using std::stack;
/**********************************************************************/
/****************************   声明   ********************************/
/**********************************************************************/
// 二叉树结点类
class TreeNode
{
public:
    int elem;
    TreeNode * lChild;
    TreeNode * rChild;
public:
    TreeNode():elem(0), lChild(NULL), rChild(NULL){}
    int display(){ cout << elem; return 0;}
}* head(NULL);
// 前序遍历
int preOrderRecursion(TreeNode* node);  // 递归
int preOrder(TreeNode* node);           // 非递归
// 中序遍历
int inOrderRecursion(TreeNode* node);   // 递归
int inOrder(TreeNode* node);            // 非递归
// 后序遍历
int postOrderRecursion(TreeNode * node);// 递归
int postOrder(TreeNode* node);          // 非递归
/**********************************************************************/
/****************************   实现  *********************************/
/**********************************************************************/
// 前序遍历-递归
int preOrderRecursion(TreeNode* node)
{
    if(NULL == node){
        return 0;
    }
    node -> display();       // 显示本节点
    preOrderRecursion(node -> lChild);   // 左孩子
    preOrderRecursion(node -> rChild);   // 右孩子
    return 0;
}
// 前序遍历-非递归(递归思想)
int preOrder(TreeNode* node)
{
    stack<TreeNode*> s;
    s.push(node);
      
    while(!s.empty()){
        node = s.top();
        s.pop();
        node -> display();
        if(NULL != node -> lChild){
            s.push(node -> lChild);
        }
        if(NULL != node -> rChild){
            s.push(node -> rChild);
        }
    }
    return 0;
}
// 前序遍历-非递归(深度遍历思想)[归纳法]
int preOrder2(TreeNode* node)
{
    stack<TreeNode*> s;
      
    while(NULL != node || !s.empty()){
       while(NULL != node){
           node -> display();
           s.push(node);
           node = node -> lChild;
       }
       if(!s.empty()){
           node = s.top();
           s.pop();
           node = node -> rChild;
       }
    }
    return 0;
}
// 中序遍历-递归
int inOrderRecursion(TreeNode* node)
{
    if(NULL == node){
        return 0;
    }
    inOrderRecursion(node -> lChild);    // 左孩子
    node -> display();                   // 显示本结点
    inOrderRecursion(node -> rChild);    // 右孩子
    return 0;
}
// 中序遍历-非递归(树的某结点的五种形式的思想)
int inOrder(TreeNode* node)
{
    stack<TreeNode*> s;
      
    // 节点有五种状态:
    // 1.双节点,2.只有左孩子 3.只有右孩子 4.叶子  5.非结点
    // 动态的,再划分两种状态:(程序使用bool作为开关)
    // 1.进入态  2.回朔态
    // 一共是5*2=10种状态
    bool entrance = true;
    while(NULL != node){
        if(entrance){   // 进入态
            // 1.双节点  2. 只有左孩子,两种状态使用同一种方法
            if(NULL != node -> lChild){
                s.push(node);
                node = node -> lChild;
                continue;
            }
            // 3. 只有右孩子
            else if(NULL != node -> rChild){
                node -> display();
                node = node -> rChild;
                continue;
            }
        }
        else{           // 回朔态
            // 1. 双节点
            if(NULL != node -> lChild && NULL != node -> rChild){
                node -> display();
                node = node -> rChild;
                entrance = true;            // 转换为进入态
                continue;
            }
            // 2. 只有左孩子
            else if(NULL != node -> lChild){
                node -> display();
                node = s.top();
                s.pop();
                continue;
            }
        }
        // 4. 叶子结点
        if(NULL == node -> lChild && NULL == node -> rChild){
            node -> display();
        // 5.(如果往下遍历的话)非结点的回溯
            if(!s.empty()){
                node = s.top();
                s.pop();
                entrance = false;
            }
            else{
                node = NULL;    // 方便下次跳出循环
            }
        }  
    }
    return 0;
}
// 中序遍历-非递归(深度遍历思想)[归纳法]
int inOrder2(TreeNode* node)
{
    stack<TreeNode*> s;
    s.push(node);
      
    while(!s.empty()){
        while(NULL != node){
            s.push(node -> lChild);
            node = node -> lChild;
        }
        if(!s.empty()){
            node = s.top();
            s.pop();
            node -> display();
            node = node -> rChild;
        }
    }
    return 0;
}
// 后序遍历-递归
int postOrderRecursion(TreeNode * node)
{
    if(NULL == node){
        return 0;
    }
    postOrderRecursion(node -> lChild);  // 左子树访问
    postOrderRecursion(node -> rChild);  // 右子树访问
    node -> display();                   // 显示本节点
    return 0;
}
// 后序遍历-非递归(树的某结点的五种形式的思想)
int postOrder(TreeNode* node)
{
    stack<TreeNode*> s;
    bool entrance = true;
    // 节点有五种状态:
    // 1.双节点,2.只有左孩子 3.只有右孩子 4.叶子  5.非结点
    // 动态的,再划分两种状态:(程序使用bool作为开关)
    // 1.进入态  2.回朔态
    while(NULL != node){
        if(entrance){
            // 1.双孩子
            if(NULL != node -> lChild && NULL != node -> rChild){
                s.push(node);           // 存本节点
                s.push(node -> rChild);  // 存双重右结点(也是作为双结点的标志)
                s.push(node -> rChild);
                node = node -> lChild;   // 进入左结点
                continue;
            }
            // 2.左孩子
            else if(NULL != node -> lChild){
                s.push(node);           // 存本结点
                node = node -> lChild;
                continue;
            }
            // 3.右孩子
            else if(NULL != node -> rChild){
                s.push(node);           // 存本结点
                node = node -> rChild;
                continue;
            }
            // 4.叶子
            else if(NULL == node -> lChild && NULL == node -> rChild){
                node -> display();       // 显示结点
            }
        }
        else{
            // 回溯态,1.2.3.4均显示结点
            node -> display();
        }
        // 5. 无结点,开始回溯
        if(s.empty()){
            node = s.top();
            s.pop();
            if(!s.empty()){ // 判断是否右结点
                if(s.top() == node){
                    entrance = true;    // 转换为进入态
                    continue;
                }
            }
            entrance = false;
        }
    }
    return 0;
}
// 主函数
int main()
{
    system("pause");
    return 0;
}