【大话数据结构】二叉树的遍历(前序 中序 后续 层次 深度优先 广度优先 DFS BFS)

书籍推荐

《大话数据结构》——https://www.geekschool.club/book/detail/20006

二叉树的遍历

二叉树的遍历方式有两类:深度优先遍历和广度优先遍历。

深度优先遍历

深度优先遍历是指顺着某一条路径尽可能的向前探索,必要的时候(探索到叶子节点)回溯。

遍历顺序:

  • 先根序遍历(DLR)
  • 中根序遍历(LDR)
  • 后根序遍历(LRD)

实现方法:

  • 递归方法

      给定一个二叉树,返回它的中序 遍历。
      示例:
    
      输入: [1,null,2,3]
         1
          \
           2
          /
         3
    
      输出: [1,3,2]
    
      来源:力扣(LeetCode)
      链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal
    
      # Definition for a binary tree node.
      # class TreeNode(object):
      #     def __init__(self, x):
      #         self.val = x
      #         self.left = None
      #         self.right = None
      class Solution(object):
          def inorderTraversal(self, root):
              """
              :type root: TreeNode
              :rtype: List[int]
              """
              assert isinstance(root, TreeNode). TypeError
              if not root:
                  return []
              return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)
    
  • 循环迭代方法

    先根序遍历(DLR):

      class Solution(object):
          def inorderTraversal(self, root):
              i = root
              result = []
              stack = []
              while i or stack: # 判断整棵树是否遍历完成
                  while i: # 判断是否达到叶子节点
                      result.append(i.val) # 先遍历根节点
                      stack.append(i.right) # 右子树入栈,待会儿遍历
                      i = i.left # 深入左子树
                  i = stack.pop() # 取出右子树
              return result
    

    中根序遍历(LDR):

      class Solution(object):
          def inorderTraversal(self, root):
              i = root
              result = []
              stack = []
              while i or stack:
                  while i:
                      stack.append(i)
                      i = i.left
                  i = stack.pop()
                  result.append(i.val)
                  i = i.right
              return result
    

    后根序遍历(LRD):

      class Solution(object):
          def inorderTraversal(self, root):
              i = root
              result = []
              stack = []
              while i or stack:
                  while i:
                      stack.append(i)
                      i = i.left or i.right
                  i = stack.pop()
                  result.append(i.val)
                  if stack and i == stack[-1].left:
                      i = stack[-1].right
                  else:
                      i = None
              return result
    

广度优先遍历

广度优先遍历是指在所有子树路径上齐头并进。

遍历顺序:

  • 层次遍历

实现方法

  • 队列循环迭代

      from Queue import Queue
      class Solution(object):
          def inorderTraversal(self, root):
              result = []
              q = Queue()
              q.input(root)
              while not q.empty():
                  item = q.get()
                  if item:
                      if item.left:
                          q.put(item.left)
                      if item.right:
                          q.put(item.right)
                      result.append(item.val)
              return result
    
  • 双层列表迭代

      class Solution(object):
          def inorderTraversal(self, root):
              result = []
              if not root:
                  return result
              cur_nodes = [root]
              while cur_nodes:
                  sub_result = []
                  next_nodes = []
                  for node in cur_nodes:
                      if node:
                          sub_result.append(node.val)
                          if node.left:
                              next_nodes.append(node.left)
                          if node.right:
                              next_nodes.append(node.right)  
                  result.append(sub_result)
                  cur_nodes = next_nodes
              return result
    

问题变种

  • 根据先根序遍历和中根序遍历结果,恢复一颗二叉树

      根据一棵树的前序遍历与中序遍历构造二叉树。
    
      注意:
      你可以假设树中没有重复的元素。
    
      例如,给出
    
      前序遍历 preorder = [3,9,20,15,7]
      中序遍历 inorder = [9,3,15,20,7]
      返回如下的二叉树:
    
          3
         / \
        9  20
          /  \
         15   7
    
    
      来源:力扣(LeetCode)
      链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
      # Definition for a binary tree node.
      # class TreeNode(object):
      #     def __init__(self, x):
      #         self.val = x
      #         self.left = None
      #         self.right = None
    
      class Solution(object):
          def buildTree(self, preorder, inorder):
              """
              :type preorder: List[int]
              :type inorder: List[int]
              :rtype: TreeNode
              """
              if not preorder:
                  return None
              root = TreeNode(preorder[0])
              mid = inorder.index(preorder[0])
              root.left = self.buildTree(preorder[1: mid+1], inorder[:mid])
              root.right = self.buildTree(preorder[mid+1:], inorder[mid+1:])
              return root
    

你可能感兴趣的:(数据结构)