0
点赞
收藏
分享

微信扫一扫

数据结构与算法----学习笔记(6)二叉树实战部分2

仲秋花似锦 2022-05-03 阅读 45

二叉树的遍历相关题目

再去动手实现二叉树的三种遍历,分别使用递归、迭代、颜色标记法

以深度优先搜索为原型的遍历

144二叉树的前序遍历
94二叉树的中序遍历
145二叉树的后序遍历
可能涉及:Morris 遍历方法


以广度优先搜索为原型的遍历,在树中称为层序遍历

LeetCode 中有三种:自顶向下层序、自底向上层序、锯齿层序遍历。
102二叉树的层次遍历
103二叉树的锯齿形层次遍历
107二叉树的层次遍历 ii
116填充每个节点的下一个右侧节点指针
117填充每个节点的下一个右侧节点指针 ii


144二叉树的前序遍历
解法一:迭代
解法二:递归
解法三:颜色标记法
其核心思想是使用颜色标记节点的状态
新节点为白色 已访问的节点为灰色:如果遇到的节点为白色,则将其标记为灰色,然后将其右子节点 、 左子节点 、 自身依次入栈 。
如果遇到的节点为灰色,则将节点的值输出 。
颜色标记法的优势:兼具栈迭代方法的高效,又像递归方法一样简洁易懂 更重要的是这种方法对于前序 、 中序 、 后序遍历 能够写出完全一致的代码 。

class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None:
            return []
        white,gray =0,1
        stack = [(root,white)]
        result = []
        while stack:
            node,color = stack.pop()
            if node != None:
                if color == white:
                    stack.append((node.right,white))
                    stack.append((node.left,white)) 
                    stack.append((node,gray))
                else:
                    result.append(node.val)

        return result

94二叉树的中序遍历
递归

class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None:
            return []
        result = [root.val]
        left_val = self.inorderTraversal(root.left)
        right_val = self.inorderTraversal(root.right)

        return left_val + result + right_val

迭代

class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None:
            return []
        stack = []
        output = []
        p_node = root
        while stack or p_node:

            # 一直找到最左边的结点
            while p_node:
                stack.append(p_node)
                p_node = p_node.left
            # 弹出栈顶的结点
            cur_node = stack.pop()
            output.append(cur_node.val)
            # 如果当前结点有右孩子,则指向右孩子,从而继续找左孩子
            if cur_node.right:
                p_node  = cur_node.right
        return output

颜色标记法

class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None:
            return []
        
        white,gray = 0,1
        stack = [(white,root)]
        output = []

        while stack:
            color ,node = stack.pop()
            if node!= None:
                if color == white:
                    stack.append((white,node.right))
                    stack.append((gray,node))
                    stack.append((white,node.left))
                else:
                    output.append(node.val)
        return output

145二叉树的后序遍历

class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None:
            return []
        result = []
        result.append(root.val)
        left_item = self.postorderTraversal(root.left)
        right_item = self.postorderTraversal(root.right)
        return left_item + right_item + result
class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None:
            return []
        stack = [root]
        result = []
        while stack:
            node = stack.pop()

            if node != None:
                # 左右根   根右左
                result.append(node.val)
                stack.append(node.left)
                stack.append(node.right)
        return result[::-1]
class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None:
            return []
        white ,gray = 0,1
        stack = [(white,root)]
        result = []
        while stack:
            color,node = stack.pop()
            if node!= None:
                if color == white:
                    stack.append((gray,node))
                    stack.append((white,node.right))
                    stack.append((white,node.left))
                else:
                    result.append(node.val)

        return result

广度优先

102二叉树的层次遍历
迭代

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if root == None:
            return []
        dequeue = [root]
        result = []
        while dequeue:
            length = len(dequeue)
            ceng = []
            for _ in range(length):
                node = dequeue.pop(0)
                if node.left :
                    dequeue.append(node.left)
                if node.right:
                    dequeue.append(node.right)
                ceng.append(node.val)
            result.append(ceng)
        return result

递归

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if root == None:
            return []
        res = []
    
        def dfs(index,node):
            if len(res) < index:
                res.append([])
            res[index-1].append(node.val)
            if node.left:
                dfs(index+1,node.left)
            if node.right:
                dfs(index+1,node.right)
        dfs(1,root)
        return res 

103二叉树的锯齿形层次遍历

class Solution:
    def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
        if root == None:
            return []
        import collections
        queue = collections.deque()
        queue.append(root)
        index = 1
        res = []
        while queue:
            length = len(queue)
            temp = []
            for _ in range(length):
                node = queue.popleft()
                temp.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right :
                    queue.append(node.right)
            if (index&1)==1:
                res.append(temp)
            else:
                res.append(temp[::-1])
            index +=1
        return res

class Solution:
    def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
        if root == None:
            return []
        res = []
        import collections
        def dfs(index,node):
            if len(res) < index:
                res.append(collections.deque())
            if index%2:
                res[index-1].append(node.val)
            else:
                res[index-1].appendleft(node.val)
            if node.left:
                dfs(index+1,node.left)
            if node.right:
                dfs(index+1,node.right)
        dfs(1,root)
        return [list(q) for q in res]

107二叉树的层次遍历 ii

class Solution:
    def levelOrderBottom(self, root: TreeNode) -> List[List[int]]:
        if root == None:
            return []
        queue= [root]
        result = []        
        while queue:
            length = len(queue)
            temp= []
            for _ in range(length):
                node = queue.pop(0)
                temp.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            result.append(temp)
        return result[::-1]

class Solution:
    def levelOrderBottom(self, root: TreeNode) -> List[List[int]]:
        if root == None:
            return []
        queue= [root]
        import collections
        result = collections.deque()        
        while queue:
            length = len(queue)
            temp= []
            for _ in range(length):
                node = queue.pop(0)
                temp.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            
            result.appendleft(temp)
        return list(result)
class Solution:
    def levelOrderBottom(self, root: TreeNode) -> List[List[int]]:
        if root == None:
            return []
        res = []
        def dfs(index,node):
            if len(res)<index:
                res.append([])
            res[index-1].append(node.val)

            if node.left:
                dfs(index+1,node.left)
            if node.right:
                dfs(index+1,node.right)
        dfs(1,root)
        return res[::-1]

116填充每个节点的下一个右侧节点指针

class Solution:
    def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
        if not root:
            return root
        queue= [root]
        res = []
        while queue:
            length = len(queue)
            temp = queue[0]
            for i in range(1,length):
                temp.next = queue[i]
                temp = queue[i]
            for _ in range(length):
                node = queue.pop(0)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return root

class Solution:
    def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
        if not root:
            return root
        pre = root
        while pre.left:
            temp = pre
            while temp:
                temp.left.next = temp.right

                if temp.next:
                    temp.right.next = temp.next.left
                temp = temp.next
            pre = pre.left
        return root

class Solution:
    def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
        def dfs(node):
            if not node:
                return node
            left = node.left
            right = node.right
            while left:
                left.next = right
                left = left.right
                right = right.left
            dfs(node.left)
            dfs(node.right)
        dfs(root)
        return root

117填充每个节点的下一个右侧节点指针 ii

class Solution:
    def connect(self, root: 'Node') -> 'Node':
        if root == None:
            return root
        queue = [root]
        while queue:
            length = len(queue)
            temp = queue[0]
            for i in range(1,length):
                temp.next = queue[i]
                temp = queue[i]
            for _ in range(length):
                temp = queue.pop(0)
                if temp.left:
                    queue.append(temp.left)
                if temp.right:
                     queue.append(temp.right)
        return root
class Solution:
    def connect(self, root: 'Node') -> 'Node':
        if root == None:
            return root
        
        rootNode = root
        oneNode_next = None
        first_next = None

        while rootNode:
            if rootNode.left:
                if not first_next:
                    first_next = rootNode.left
                if oneNode_next :
                    oneNode_next.next = rootNode.left
                oneNode_next = rootNode.left
            
            if rootNode.right:
                if not first_next :
                    first_next = rootNode.right
                if oneNode_next:
                    oneNode_next.next = rootNode.right
                oneNode_next = rootNode.right
            
            rootNode = rootNode.next
            if not rootNode:
                rootNode = first_next
                first_next = None
                oneNode_next = None
        return root 
举报

相关推荐

0 条评论