1. 程式人生 > >leetcode-二叉樹的前中後遍歷(94、144、145)

leetcode-二叉樹的前中後遍歷(94、144、145)

中序遍歷

中序遍歷的順序:左中右

思路

  1. 遞迴

每次遞迴,只需要判斷結點是不是None,否則按照左中右的順序打印出結點value值

class Solution:
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return [] 
        return self.inorderTraversal(
root.left) + [root.val] + self.inorderTraversal(root.right)
  1. 迴圈
    迴圈比遞迴要複雜得多,因為你得在一個函式中遍歷到所有結點。
    對於樹的遍歷,迴圈操作基本上要用到棧(stack)這個結構
    對於中序遍歷的迴圈實現,每次將當前結點(curr)的左子結點push到棧中,直到當前結點(curr)為None。這時,pop出棧頂的第一個元素,設其為當前結點,並輸出該結點的value值,且開始遍歷該結點的右子樹。在這裡插入圖片描述

在這裡插入圖片描述
規律為:當前結點curr不為None時,每一次迴圈將當前結點curr入棧;當前結點curr為None時,則出棧一個結點,且打印出棧結點的value值。整個迴圈在stack和curr皆為None的時候結束。

class Solution:
    def inorderTraversal(self, root):
        stack = []
        sol = []
        curr = root
        while stack or curr:
            if curr:
                stack.append(curr)
                curr = curr.left
            else:
                curr = stack.pop()
                sol.
append(curr.val) curr = curr.right return sol

前序和後序

前序遍歷指根結點在最前面輸出,所以前序遍歷的順序是:中左右
後序遍歷指根結點在最後面輸出,所以後序遍歷的順序是:左右中

遞迴

class Solution:
    def preorderTraversal(self, root):  ##前序遍歷
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return [] 
        return  [root.val] + self.inorderTraversal(root.left) + self.inorderTraversal(root.right)
        
    def postorderTraversal(self, root):  ##後序遍歷
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return [] 
        return  self.inorderTraversal(root.left) + self.inorderTraversal(root.right) + [root.val]

迴圈

先看前序遍歷。我們仍然使用棧stack,由於前序遍歷的順序是中左右,所以我們每次先列印當前結點curr,並將右子結點push到棧中,然後將左子結點設為當前結點。入棧和出棧條件(當前結點curr不為None時,每一次迴圈將當前結點curr入棧;當前結點curr為None時,則出棧一個結點)以及迴圈結束條件(整個迴圈在stack和curr皆為None的時候結束)與中序遍歷一模一樣。

再看後序遍歷。由於後序遍歷的順序是左右中,我們把它反過來,則遍歷順序變成中左右,是不是跟前序遍歷只有左右結點的差異了呢?然而左右的差異僅僅就是.left和.right的差異,在程式碼上只有機械的差別。

class Solution:
    def preorderTraversal(self, root):  ## 前序遍歷
        stack = []
        sol = []
        curr = root
        while stack or curr:
            if curr:
                sol.append(curr.val)
                stack.append(curr.right)
                curr = curr.left
            else:
                curr = stack.pop()
        return sol
        
    def postorderTraversal(self, root): ## 後序遍歷
        stack = []
        sol = []
        curr = root
        while stack or curr:
            if curr:
                sol.append(curr.val)
                stack.append(curr.left)
                curr = curr.right
            else:
                curr = stack.pop()
        return sol[::-1]