樹常考題 ( python 實現)--- 待更新

前中後序遍歷二叉樹 6 道 ( 遞歸 + 非遞歸)

遞歸忽略
前序遍歷

準備一個 stack, 因爲是前序,頭結點要先打印,則放入頭節點後立馬彈出, 在彈出的時候查詢是否有孩子節點,按照先右後左的順序壓入棧中。

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        stack = [root]
        res = []
        while stack:
            pop = stack.pop()
            if pop.right: 
                stack.append(pop.right)
            if pop.left: 
                stack.append(pop.left)
            res.append(pop.val)
        return res 
中序遍歷

stack 備好, 有左孩子就一直放,放到不能再放就彈出, 因爲中序遍歷爲 左 -> 中 -> 右, 左邊彈出後下一個 彈出爲 中, 有右再放入

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        res,stack = [], []
        cur = root
        while cur or stack:
            while cur:
                stack.append(cur)
                cur = cur.left
            pop = stack.pop()
            cur = pop.right
            res.append(pop.val)
        return res 
後序遍歷

依然準備stack,如果我們正向收集數組,先收集 中, 再收集左, 最後右, 整個翻過來就是後序的順序

class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        if not root :
            return []
        stack, res = [root],[]
        while stack:
            pop = stack.pop()
            res.append(pop.val)
            if pop.left:
                stack.append(pop.left)
            if pop.right:
                stack.append(pop.right)
        return res[::-1]

其他遍歷

層次遍歷
zig zag 遍歷

搜索二叉樹相關

左中右大小順序滿足: 小 中 大, 這樣的構造就是搜索二叉樹, 換言之,右邊的子樹都大於 左, 中

判斷是否爲搜索二叉樹

遞歸

嚴格按照定義出發, 左邊的小於中間,中間小於右邊

class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        # 如果 head.val 在兩個數之間,則爲 true,
        def helper(head, smaller, bigger):
            if not head:
                return True
            if smaller >= head.val or head.val >= bigger:
                return False
            # 左子樹, head.val 爲最大的數字
            if not helper(head.left, smaller, head.val):
                return False 
            # 右子樹, head.val 爲最小的數字
            if not helper(head.right, head.val, bigger):
                return False
            return True 
        
        return helper(root, -sys.maxsize, sys.maxsize)
中序

省略了,直接收集到結果,看一下是不是升序就好

將有序數組轉化爲平衡搜索二叉樹

看起來有平衡貌似多了個條件,其實是幫助我們做題, 有序數組中位可以作爲搜索二叉樹的頭節點, 中位數之前爲左樹,中位數之後爲右樹,遞歸。

class Solution:
    def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
        if not nums:
            return None 
        def InOrderSort(arr)-> TreeNode:
            if not arr:
                return 
            mid = len(arr) // 2 
            node = TreeNode(arr[mid])
            node.left = InOrderSort(arr[:mid])
            node.right = InOrderSort(arr[mid + 1:])
            return node 
        return InOrderSort(nums)

構造樹

前序與中序遍歷構造二叉樹

前序遍歷數組,第一個元素是整個樹的頭結點,在中序列遍歷中, 頭結點左邊右邊便是這個樹的左子樹與右子樹,遞歸構造

class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        if len(preorder) != len(inorder):
            return None 
        
        def build(preo, ino):
            if not preo or not ino:
                return 
            root_val = preo[0]
            left_len = 0
            for i in range(len(ino)):
                if root_val == ino[i]:
                    # 從零開始,左邊的長度與根節點的index一致
                    left_len = i
                    break
            root = TreeNode(root_val)
            root.left = build(preo[1: left_len + 1], ino[:left_len])
            root.right = build(preo[left_len + 1:], ino[left_len + 1:]) 
            return root 
        return build(preorder, inorder)

後序與中序遍歷構造二叉樹

思路與上題相似, 後序遍歷中,根節點在數組的最後位置,其他與上題幾乎無差別,這裏使用下py api 來做

class Solution:
    def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
        if not inorder:
            return None
        root = TreeNode(postorder[-1])
        i = inorder.index(root.val)
        root.left = self.buildTree(inorder[:i], postorder[:i])
        root.right = self.buildTree(inorder[i+1:], postorder[i:-1])
        return root
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章