二叉樹遍歷的循環(huán)解

94 Binary Tree Inorder Traversal

二叉樹中序遍歷的循環(huán)解

常規(guī)思路:

向左找到盡頭,彈出一個節(jié)點,指針指向彈出節(jié)點的右孩子 繼續(xù)循環(huán)

def inorderTraversal(self, root):
    """
    :type root: TreeNode
    :rtype: List[int]
    """
    # if not root:
    #     return []
    res, stack = [], []
    p = root
    while stack or p: # 中序遍歷處理完左側(cè)分支和根節(jié)點之后 棧空 所以只用stack做條件不合理
        while p:
            stack.append(p)
            p = p.left
        cur = stack.pop() # 左邊走到盡頭 彈出最左節(jié)點
        res.append(cur.val)
        # while stack and not cur.right: # 希望彈出的節(jié)點的右孩子存在  這樣就找到一個接盤俠 類似于遞歸的感覺
        #     cur = stack.pop() # 但是你怎么能保證就存在呢? p 還是有可能是空的 所以不用折騰
        #     res.append(cur.val)
        p = cur.right # 很像遞歸
    return res

將兩層while循環(huán)簡化成一層 仔細分析和上面的代碼思路一抹一樣

def inorderTraversal(self, root):
    res, stack = [], []
    p = root # 定義一個指針
    while stack or p:
        if p: # 進棧 往左
            stack.append(p)
            p = p.left
        else: # 出棧 往右 (左邊走到盡頭)
            node = stack.pop()
            res.append(node.val)
            p = node.right # 嘗試向右邊跑 如果這個節(jié)點存在 就是遞歸 不存在 就繼續(xù)彈出棧內(nèi)節(jié)點
    return res

節(jié)點狀態(tài)標記法

中序遍歷順序:左根右
難點在于訪問到根節(jié)點的時候并不是現(xiàn)在就要處理該節(jié)點(打印該節(jié)點)
而是要去該節(jié)點的左孩子繼續(xù)向下訪問,
只有當左孩子部分全部處理完畢,再次訪問到根節(jié)點的時候才是處理根節(jié)點的時候
所以給每一個節(jié)點設(shè)置一個狀態(tài),用于標記該節(jié)點之前是否見過,當某個節(jié)點第二次訪問的時候就是該處理的時候

def inOrder(root):
    res, stack = [], [(root, False)]
    while stack:
        node, vis = stack.pop()
        if node:
            if vis:
                res.append(node.val)
            else: # 注意堆棧元素順序和根左右恰好相反
                stack.append((node.right, False))
                stack.append((node, True))
                stack.append((node.left, False))
    return res

二叉樹前序遍歷、后序遍歷循環(huán)解 leetcode 144 145

對于前序遍歷,因為根節(jié)點一開始就被用掉,所以很方便

def preorderTraversal(self, root):
    """
    :type root: TreeNode
    :rtype: List[int]
    """
    res, stack = [], [root]
    while stack:
        node = stack.pop()
        if node:
            # pre-order, right first 這樣left位于棧頂 所以是根左右
            res.append(node.val)
            stack.append(node.right)
            stack.append(node.left) 
    return res

對于后序遍歷 根節(jié)點最后處理 所以需要一直在棧底

節(jié)點狀態(tài)標記法

對于每一個節(jié)點給一個狀態(tài),用于標記這個節(jié)點是第一次訪問還是第二次訪問,第二次訪問才是真正處理該節(jié)點的時候(打印該節(jié)點)

def postorderTraversal(self, root):
    """
    :type root: TreeNode
    :rtype: List[int]
    """
    res, stack = [],  [(root, False)]
    while stack:
        node, vis = stack.pop()
        if node:
            if vis: # 左右孩子處理完畢
                res.append(node.val)
            else:
                stack.append((node, True)) # 成功地將根節(jié)點放在了棧底
                stack.append((node.left, False))
                stack.append((node.right, False))
    return res

二叉樹的層序遍歷

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容