摘要:文章目錄二叉樹的前序遍歷二叉樹的中序遍歷二叉樹的后序遍歷二叉樹的前序遍歷在不使用遞歸的方式遍歷二叉樹時,我們可以使用一個棧模擬遞歸的機制。
在不使用遞歸的方式遍歷二叉樹時,我們可以使用一個棧模擬遞歸的機制。二叉樹的前序遍歷順序是:根 → 左子樹 → 右子樹,我們可以先將二叉樹的左路結(jié)點入棧,在入棧的同時便對其進(jìn)行訪問,此時就相當(dāng)于完成了根和左子樹的訪問,當(dāng)左路結(jié)點入棧完畢后再從棧頂依次取出結(jié)點,并用同樣的方式訪問其右子樹即可。
具體步驟如下:
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é)點入棧,入棧的同時訪問左路結(jié)點 while (cur) { st.push(cur); ret.push_back(cur->val); cur = cur->left; } //2、取出棧頂結(jié)點 TreeNode* top = st.top(); st.pop(); //3、準(zhǔn)備訪問其右子樹 cur = top->right; } return ret; //返回前序遍歷結(jié)果 }};
二叉樹的中序遍歷順序是:左子樹 → 根 → 右子樹,我們可以先將二叉樹的左路結(jié)點入棧,當(dāng)左路結(jié)點入棧完畢后,再從棧頂依次取出結(jié)點,在取出結(jié)點的同時便對其進(jìn)行訪問,此時就相當(dāng)于先訪問了左子樹再訪問了根,之后再用同樣的方式訪問取出結(jié)點的右子樹即可。
具體步驟如下:
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é)點入棧 while (cur) { st.push(cur); cur = cur->left; } //2、取出棧頂結(jié)點并訪問 TreeNode* top = st.top(); st.pop(); ret.push_back(top->val); //3、準(zhǔn)備訪問其右子樹 cur = top->right; } return ret; //返回中序遍歷結(jié)果 }};
二叉樹的后序遍歷順序是:左子樹 → 右子樹 → 根,我們可以先將二叉樹的左路結(jié)點入棧,當(dāng)左路結(jié)點入棧完畢后,再觀察棧頂結(jié)點,若棧頂結(jié)點的右子樹為空,或棧頂結(jié)點的右子樹已經(jīng)被訪問過了,則棧頂結(jié)點可以出棧并訪問,若棧頂結(jié)點的右子樹還未被訪問,則用同樣的方式訪問棧頂結(jié)點的右子樹,直到其右子樹被訪問后再訪問該結(jié)點,這時的訪問順序遵循了二叉樹的后序遍歷所要求的順序。
具體步驟如下:
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é)點 while (cur || !st.empty()) { //1、將左路結(jié)點入棧 while (cur) { st.push(cur); cur = cur->left; } //2、取出棧頂結(jié)點 TreeNode* top = st.top(); //3、若取出結(jié)點的右子樹為空,或右子樹已經(jīng)訪問過了,則訪問該結(jié)點 if (top->right == nullptr || top->right == prev) { //訪問top結(jié)點后將其從棧中彈出 st.pop(); ret.push_back(top->val); //更新上一次訪問的結(jié)點為top prev = top; } else //4、若取出結(jié)點的右子樹還未被訪問,則準(zhǔn)備訪問其右子樹 { cur = top->right; } } return ret; //返回后序遍歷結(jié)果 }};
注意: 看動圖演示時請結(jié)合所給代碼,動圖是嚴(yán)格按照代碼的邏輯制作的。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/124503.html
摘要:當(dāng)集合為空時,稱該二叉樹為空二叉樹。也就是說,如果一個二叉樹的層數(shù)為,且結(jié)點總數(shù)是,則它就是滿二叉樹。完全二叉樹完全二叉樹是效率很高的數(shù)據(jù)結(jié)構(gòu),完全二叉樹是由滿二叉樹而引出來的。 ...
摘要:在數(shù)據(jù)結(jié)構(gòu)領(lǐng)域?qū)?yīng)樹結(jié)構(gòu)來說二叉樹是最常用的一種樹結(jié)構(gòu),二叉樹具有一個唯一的根節(jié)點,也就是最上面的節(jié)點。二叉樹每個節(jié)點最多有兩個孩子,一個孩子都沒有的節(jié)點通常稱之為葉子節(jié)點,二叉樹每個節(jié)點最多有一個父親,根節(jié)點是沒有父親節(jié)點的。 showImg(https://segmentfault.com/img/remote/1460000018597053?w=1832&h=9943); 前言...
摘要:在數(shù)據(jù)結(jié)構(gòu)領(lǐng)域?qū)?yīng)樹結(jié)構(gòu)來說二叉樹是最常用的一種樹結(jié)構(gòu),二叉樹具有一個唯一的根節(jié)點,也就是最上面的節(jié)點。二叉樹每個節(jié)點最多有兩個孩子,一個孩子都沒有的節(jié)點通常稱之為葉子節(jié)點,二叉樹每個節(jié)點最多有一個父親,根節(jié)點是沒有父親節(jié)點的。 showImg(https://segmentfault.com/img/remote/1460000018597053?w=1832&h=9943); 前言...
閱讀 2390·2021-11-24 10:31
閱讀 3443·2021-11-23 09:51
閱讀 2254·2021-11-15 18:11
閱讀 2404·2021-09-02 15:15
閱讀 2465·2019-08-29 17:02
閱讀 2298·2019-08-29 15:04
閱讀 846·2019-08-29 12:27
閱讀 2870·2019-08-28 18:15