對二叉樹之前序遍歷、中序遍歷、後序遍歷三種方式遞歸及非遞歸的方式遍歷樹。node
/** * 文件名: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; }