C++ 非遞歸實(shí)現(xiàn)二叉樹的前中后序遍歷
二叉樹的前序遍歷
在不使用遞歸的方式遍歷二叉樹時(shí),我們可以使用一個(gè)棧模擬遞歸的機(jī)制。二叉樹的前序遍歷順序是:根 → 左子樹 → 右子樹,我們可以先將二叉樹的左路結(jié)點(diǎn)入棧,在入棧的同時(shí)便對其進(jìn)行訪問,此時(shí)就相當(dāng)于完成了根和左子樹的訪問,當(dāng)左路結(jié)點(diǎn)入棧完畢后再從棧頂依次取出結(jié)點(diǎn),并用同樣的方式訪問其右子樹即可。
具體步驟如下:
- 將左路結(jié)點(diǎn)入棧,入棧的同時(shí)訪問左路結(jié)點(diǎn)。
- 取出棧頂結(jié)點(diǎn)top。
- 準(zhǔn)備訪問top結(jié)點(diǎn)的右子樹。
struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode() : val(0), left(nullptr), right(nullptr) {} TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} }; class Solution { public: //前序遍歷 vector<int> preorderTraversal(TreeNode* root) { stack<TreeNode*> st; //輔助棧 vector<int> ret; //用于存放前序遍歷的結(jié)果 TreeNode* cur = root; while (cur || !st.empty()) { //1、將左路結(jié)點(diǎn)入棧,入棧的同時(shí)訪問左路結(jié)點(diǎn) while (cur) { st.push(cur); ret.push_back(cur->val); cur = cur->left; } //2、取出棧頂結(jié)點(diǎn) TreeNode* top = st.top(); st.pop(); //3、準(zhǔn)備訪問其右子樹 cur = top->right; } return ret; //返回前序遍歷結(jié)果 } };
二叉樹的中序遍歷
二叉樹的中序遍歷順序是:左子樹 → 根 → 右子樹,我們可以先將二叉樹的左路結(jié)點(diǎn)入棧,當(dāng)左路結(jié)點(diǎn)入棧完畢后,再從棧頂依次取出結(jié)點(diǎn),在取出結(jié)點(diǎn)的同時(shí)便對其進(jìn)行訪問,此時(shí)就相當(dāng)于先訪問了左子樹再訪問了根,之后再用同樣的方式訪問取出結(jié)點(diǎn)的右子樹即可。
具體步驟如下:
- 將左路結(jié)點(diǎn)入棧。
- 取出棧頂結(jié)點(diǎn)top并訪問。
- 準(zhǔn)備訪問top結(jié)點(diǎn)的右子樹。
struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode() : val(0), left(nullptr), right(nullptr) {} TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} }; class Solution { public: //中序遍歷 vector<int> inorderTraversal(TreeNode* root) { stack<TreeNode*> st; //輔助棧 vector<int> ret; //用于存放中序遍歷的結(jié)果 TreeNode* cur = root; while (cur || !st.empty()) { //1、將左路結(jié)點(diǎn)入棧 while (cur) { st.push(cur); cur = cur->left; } //2、取出棧頂結(jié)點(diǎn)并訪問 TreeNode* top = st.top(); st.pop(); ret.push_back(top->val); //3、準(zhǔn)備訪問其右子樹 cur = top->right; } return ret; //返回中序遍歷結(jié)果 } };
二叉樹的后序遍歷
二叉樹的后序遍歷順序是:左子樹 → 右子樹 → 根,我們可以先將二叉樹的左路結(jié)點(diǎn)入棧,當(dāng)左路結(jié)點(diǎn)入棧完畢后,再觀察棧頂結(jié)點(diǎn),若棧頂結(jié)點(diǎn)的右子樹為空,或棧頂結(jié)點(diǎn)的右子樹已經(jīng)被訪問過了,則棧頂結(jié)點(diǎn)可以出棧并訪問,若棧頂結(jié)點(diǎn)的右子樹還未被訪問,則用同樣的方式訪問棧頂結(jié)點(diǎn)的右子樹,直到其右子樹被訪問后再訪問該結(jié)點(diǎn),這時(shí)的訪問順序遵循了二叉樹的后序遍歷所要求的順序。
具體步驟如下:
- 將左路結(jié)點(diǎn)入棧。
- 觀察棧頂結(jié)點(diǎn)top。
- 若top結(jié)點(diǎn)的右子樹為空,或top結(jié)點(diǎn)的右子樹已經(jīng)訪問過了,則訪問top結(jié)點(diǎn)。訪問top結(jié)點(diǎn)后將其從棧中彈出,并更新上一次訪問的結(jié)點(diǎn)為top。
- 若top結(jié)點(diǎn)的右子樹還未被訪問,則準(zhǔn)備訪問其右子樹。
struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode() : val(0), left(nullptr), right(nullptr) {} TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} }; class Solution { public: //后序遍歷 vector<int> postorderTraversal(TreeNode* root) { stack<TreeNode*> st; //輔助棧 vector<int> ret; //用于存放后序遍歷的結(jié)果 TreeNode* cur = root; TreeNode* prev = nullptr; //記錄上一次訪問的結(jié)點(diǎn) while (cur || !st.empty()) { //1、將左路結(jié)點(diǎn)入棧 while (cur) { st.push(cur); cur = cur->left; } //2、取出棧頂結(jié)點(diǎn) TreeNode* top = st.top(); //3、若取出結(jié)點(diǎn)的右子樹為空,或右子樹已經(jīng)訪問過了,則訪問該結(jié)點(diǎn) if (top->right == nullptr || top->right == prev) { //訪問top結(jié)點(diǎn)后將其從棧中彈出 st.pop(); ret.push_back(top->val); //更新上一次訪問的結(jié)點(diǎn)為top prev = top; } else //4、若取出結(jié)點(diǎn)的右子樹還未被訪問,則準(zhǔn)備訪問其右子樹 { cur = top->right; } } return ret; //返回后序遍歷結(jié)果 } };
注意: 看動(dòng)圖演示時(shí)請結(jié)合所給代碼,動(dòng)圖是嚴(yán)格按照代碼的邏輯制作的。
到此這篇關(guān)于C++ 非遞歸實(shí)現(xiàn)二叉樹的前中后序遍歷的文章就介紹到這了,更多相關(guān)二叉樹前中后序遍歷內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++關(guān)鍵字之likely和unlikely詳解
這篇文章主要介紹了C++關(guān)鍵字之likely和unlikely,C++20之前的,likely和unlikely只不過是一對自定義的宏,而C++20中正式將likely和unlikely確定為屬性關(guān)鍵字,本文給大家詳細(xì)講解,需要的朋友可以參考下2022-10-10vs2019 Com組件初探之簡單的COM編寫及實(shí)現(xiàn)跨語言調(diào)用的方法
這篇文章主要介紹了vs2019 Com組件初探之簡單的COM編寫及實(shí)現(xiàn)跨語言調(diào)用的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12使用C++實(shí)現(xiàn)MySQL數(shù)據(jù)庫連接池
這篇文章主要為大家詳細(xì)介紹了如何使用C++實(shí)現(xiàn)MySQL數(shù)據(jù)庫連接池,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以了解下2024-03-03簡單談?wù)勱P(guān)于C++中大隨機(jī)數(shù)的問題
這篇文章主要介紹了關(guān)于C++中大隨機(jī)數(shù)的問題,文中給出了詳細(xì)的示例代碼,相信對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,有需要的朋友可以一起來學(xué)習(xí)學(xué)習(xí)。2017-01-01C++中inet_pton、inet_ntop函數(shù)的用法
這篇文章主要介紹了C++中inet_pton、inet_ntop函數(shù)的用法,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08