对二叉树以前序遍历、中序遍历、后序遍历三种方式递归及非递归的方式遍历树。
/** * 文件名: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; }