昨天學習了遞歸遍歷:遞歸就是一次次的把參數壓入棧中,然后返回的時候還是上一次遞歸保存的參數。
今天學習迭代遍歷。
迭代遍歷就是用棧去模擬保存二叉樹的節點,然后依次去遍歷,只不過要注意棧的后入先出的規則。
前序遍歷:前序遍歷的順序應該是中左右,每次先處理中間節點,先把中間節點放入棧中,然后只要棧不為空就再調用一個指針去遍歷二叉樹,不過這個時候要注意:要先存放右節點,再存放左節點。
順序應該是:12453?
迭代過程:
棧初始化為
[1]
→ 彈出1
,記錄1
,壓入3, 2
(棧變為[3, 2]
)。彈出
2
,記錄2
,壓入5, 4
(棧變為[3, 5, 4]
)。彈出
4
,記錄4
(無子節點,棧變為[3, 5]
)。彈出
5
,記錄5
(無子節點,棧變為[3]
)。彈出
3
,記錄3
(無子節點,棧為空)
代碼實現:
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;TreeNode* cur = root;while (cur != NULL || !st.empty()) {if (cur != NULL) { // 指針來訪問節點,訪問到最底層st.push(cur); // 將訪問的節點放進棧cur = cur->left; // 左} else {cur = st.top(); // 從棧?彈出的數據,就是要處理的數據(放進result數組?的數據)st.pop();result.push_back(cur->val); // 中cur = cur->right; // 右}}return result;}
};
中序遍歷:
這個不能直接修改前序遍歷的代碼:
迭代思路
從根開始一路向左,把經過的節點全部壓棧(不訪問)。
彈出棧頂,訪問它(這就是“根”)。
轉向它的右子樹,重復步驟1
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> st;TreeNode* cur = root;while (cur != NULL || !st.empty()) {if (cur != NULL) { // 指針來訪問節點,訪問到最底層st.push(cur); // 將訪問的節點放進棧cur = cur->left; // 左} else {cur = st.top(); // 從棧?彈出的數據,就是要處理的數據(放進result數組?的數據)st.pop();result.push_back(cur->val); // 中cur = cur->right; // 右}}return result;}
};
后序遍歷:
這個和前序遍歷基本上一樣,只不過最后翻轉一下數組就好了。