題目地址:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/
給定一個二叉樹,返回它的中序 遍歷。
示例:
輸入: [1,null,2,3]
1
\
2
/
3
輸出: [1,3,2]
進階: 遞歸算法很簡單,你可以通過迭代算法完成嗎?
我們看一個例子:
4
/ \
2 6
/ \ / \
1 3 5 7
步驟 | 判斷條件 | 操作 | 棧 | 彈出數字 | 隊列 |
---|---|---|---|---|---|
1 | 節點4不空 | 壓入4 | 4 | ||
2 | 節點2不空 | 壓入2 | 4,2 | ||
3 | 節點1不空 | 壓入1 | 4,2,1 | ||
4 | 節點1左孩子空,棧不空 | 退棧,記錄棧頂元素1的右孩子 | 4,2 | 1 | 1 |
5 | 節點1的右孩子爲空 | 退棧,記錄棧頂元素2的右孩子3 | 4 | 2 | 1,2 |
6 | 右孩子3不空 | 壓入3 | 4,3 | 1,2 | |
7 | 節點3左孩子空,棧不空 | 退棧,記錄棧頂元素3的右孩子 | 4 | 3 | 1,2,3 |
8 | 節點3右孩子空 | 退棧,記錄棧頂元素4的右孩子 | 4 | 1,2,3,4 | |
9 | 棧空,節點4右孩子6不空 | 壓入6 | 6 | 1,2,3,4 | |
10 | 節點5不空 | 壓入5 | 6,5 | 1,2,3,4 | |
11 | 節點5左孩子空 | 退棧,記錄棧頂元素5的右孩子 | 6 | 5 | 1,2,3,4,5 |
12 | 節點5右孩子空 | 退棧,記錄棧頂元素6的右孩子 | 6 | 1,2,3,4,5,6 | |
13 | 節點6的右孩子7不空 | 壓入7 | 7 | 1,2,3,4,5,6 | |
14 | 節點7的左孩子空 | 退棧,記錄棧頂元素7的右孩子 | 7 | 1,2,3,4,5,6,7 | |
14 | 節點7的右孩子空,棧空 | 結束 | 1,2,3,4,5,6,7 |
思路
- 棧不空或者root不空時,繼續2,否則終止
- 沿着root左孩子遍歷,依次入棧,直到節點爲空
- 記錄棧頂top,棧pop,將top的右孩子設爲root,繼續1
難點:
利用迭代遍歷樹時,都要用到棧來輔助解決回溯到父節點的問題。
此解法中的一個trick:棧頂元素的右孩子節點爲空,就繼續退棧。
參考代碼
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode *> s;
TreeNode *p = root;
while (!s.empty() || p) {
if (p) {
s.push(p);
p = p->left;
continue;
}
TreeNode *q = s.top();
s.pop();
result.push_back(q->val);
p = q->right;
}
return result;
}
};