C++二叉樹前中后序遍歷(遞歸&非遞歸)統一代碼格式


統一下二叉樹的代碼格式,遞歸和非遞歸都統一格式,方便記憶管理。

 

三種遞歸格式:

 前序遍歷:

void PreOrder(TreeNode* root, vector<int>&path) { if (root) { path.emplace_back(root->val); PreOrder(root->left, path); PreOrder(root->right, path); } }

中序遍歷:

void InOrder(TreeNode* root, vector<int>& path) { if (root) { InOrder(root->left, path); path.emplace_back(root->val); InOrder(root->right, path); } }

后序遍歷:

void PostOrder(TreeNode* root, vector<int>& path) { if (root) { PostOrder(root->left, path); PostOrder(root->right, path); path.emplace_back(root->val); } }

三種遞歸遍歷不用多解釋。

 

三種非遞歸格式:

前序遍歷:

void PreOrderCycle(TreeNode* root, vector<int>& path) { stack<pair<TreeNode*, bool>> s; s.emplace(make_pair(root, false)); bool visited; while (!s.empty()) { root = s.top().first; visited = s.top().second; s.pop(); if (root == NULL) continue; if (visited) path.emplace_back(root->val); else { s.emplace(make_pair(root->right, false)); s.emplace(make_pair(root->left, false)); s.emplace(make_pair(root, true)); } } }

中序遍歷:

void InOrderCycle(TreeNode* root, vector<int>& path) { stack<pair<TreeNode*, bool>> s; s.emplace(make_pair(root, false)); bool visited; while (!s.empty()) { root = s.top().first; visited = s.top().second; s.pop(); if (root == NULL) continue; if (visited) path.emplace_back(root->val); else { s.emplace(make_pair(root->right, false)); s.emplace(make_pair(root, true)); s.emplace(make_pair(root->left, false)); } } }

后序遍歷:

void PostOrderCycle(TreeNode* root, vector<int>& path) { stack<pair<TreeNode*, bool>> s; s.emplace(make_pair(root, false)); bool visited; while (!s.empty()) { root = s.top().first; visited = s.top().second; s.pop(); if (root == NULL) continue; if (visited) path.emplace_back(root->val); else { s.emplace(make_pair(root, true)); s.emplace(make_pair(root->right, false)); s.emplace(make_pair(root->left, false)); } } }

以上三種遍歷實現代碼行數一模一樣,如同遞歸遍歷一樣,只有三行核心代碼的先后順序有區別。

解釋下三種非遞歸遍歷(以下圖舉例):

對二叉樹而言,將每個框內結點集都看做一個局部,那么局部有   A,A B C,B D E,D,E,C F G,F,G 並且可以發現每個結點元素都是相鄰的兩個局部的重合結點

算法流程:

1 每個結點元素都是相鄰的兩個局部的重合結點。對一個局部排好序后,通過取出一個重合結點過渡到與之相鄰的局部進行新的局部排序。
2 用棧來保證局部順序(排在前面的后入棧,排在后面的先入棧,保證局部元素出棧的順序一定正確)
3 通過棧頂元素過渡到新局部的排序,對新局部的排序會導致該結點再次入棧,
4 當棧頂出現已完成過渡使命的結點時,就可以徹底出棧輸出了,新棧頂元素會繼續完成新局部的過渡
5 當所有結點都完成了過渡使命了,就全部出棧了。

 

參考:

https://www.jianshu.com/p/49c8cfd07410

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM