1. 程式人生 > 其它 >Leetcode[棧] 144. 二叉樹的前序遍歷

Leetcode[棧] 144. 二叉樹的前序遍歷

技術標籤:Leetcode 棧專題二叉樹演算法資料結構迭代遍歷

Leetcode[棧] 144. 二叉樹的前序遍歷

審題

給你二叉樹的根節點 root ,返回它節點值的 前序 遍歷。

示例 1:
輸入:root = [1,null,2,3]
輸出:[1,2,3]

示例 2:
輸入:root = []
輸出:[]

示例 3:
輸入:root = [1]
輸出:[1]

示例 4:
輸入:root = [1,2]
輸出:[1,2]

示例 5:
輸入:root = [1,null,2]
輸出:[1,2]

提示:
樹中節點數目在範圍 [0, 100] 內
-100 <= Node.val <= 100
 
進階:遞迴演算法很簡單,你可以通過迭代演算法完成嗎?

看到這道題,一看,遞迴實現直接就可以AC了,然而為了掌握遞迴的底層邏輯,我們還是要搞一下迭代試一試

  1. 在方案一中,遞迴。
  2. 在方案二中,迭代(遞迴的本質就是模擬一個棧)。

程式碼實現

方案一:

常規操作,沒啥好說的。

class Solution {
public:
    void pre(TreeNode* root, vector<int>& v) {
        if (root) v.push_back(root->val);
        else return;
        pre(root->left, v);
        pre(root-
>right, v); } vector<int> preorderTraversal(TreeNode* root) { vector<int> v; pre(root, v); return v; } };

方案2:

這個迭代,我有一個地方還是每太理解,就是標註釋的地方,這個條件讓我楞想可能想不太出來…

1:這個的整體思路就是第一個迴圈,直接遍歷到最左下,這個最左下可以認為是二叉樹的最左下的左節點(一個空結點)。

2:然後將二叉樹最左下的結點pop出來

3:遍歷右結點,如果右結點為非空,繼續轉到1。如果右結點為空結點,直接將該最左下的父結點pop掉,再轉回3,以此類推。

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> v;
        if ( !root ) return v;
        stack<TreeNode*> s;
        while ( !s.empty() || root ) { //?
            while ( root ) {
                s.push(root);
                v.push_back(root->val);
                root = root->left;
            }
            root = s.top();
            s.pop();
            root = root->right;
        }
        return v;
    }
};

反思

這個棧的知識還是比較淺薄,尤其是結合了樹之後。因此,如果想要掌握好這部分的內容,我認為首要的不是求甚解,而是不求甚解,在極其細節的部分可以先記下來,以後隨著練習的增多自然會加深理解,不必搞自己心態。