數據結構與算法-基礎(八)遍歷二叉樹

遍歷是數據結構中的常見操作,就是把所有的元素遍歷一遍。

線性結構的遍歷無非是兩種,正序遍歷逆序遍歷,也就是從頭依次遍歷或者從尾依次遍歷。

二叉樹的遍歷方式有 4 種,是根據不同的節點訪問順序來區分:

遍歷方法 訪問順序 備註
前序遍歷(Preorder Traversal) 根節點、左子樹、右子樹
中序遍歷(Inorder Traversal) 左子樹、根節點、右子樹
後序遍歷(Postorder Traversal) 左子樹、右子樹、根節點
層序遍歷(Level Order Traversal) 從上到下、從左到右依次訪問每一個節點

從上面表格中可以大致總結出前三種遍歷的唯一區別就是訪問的順序不同,那麼就可以都使用遞歸的方式實現。

凡是使用遞歸方式,必須要確定一個結束遞歸的條件,因爲二叉樹的遍歷都是從根節點開始,直到所有節點都遍歷完成,所以結束遞歸的條件就是節點爲 null

// 結束遞歸條件
if (node == null) return;

前序遍歷

前序遍歷的順序是根節點、左子樹,最後右子樹

/**
 * 前序遍歷(遞歸)
 */
public void preorderTanversal() {
  preorderTanversal(root, visitor);
}
private void preorderTanversal(Node<E> node) {
  // 結束條件
  if (node == null) return;

  // 訪問根節點
  System.out.println(node.element);
  // 訪問左子樹
  preorderTanversal(node.left, visitor);
  // 訪問右子樹
  preorderTanversal(node.right, visitor);
}

中序遍歷

中序遍歷的順序是左子樹、根節點,最後右子樹

/**
 * 中序遍歷(遞歸)
 */
public void inorderTraversal() {
  preorderTanversal(root, visitor);
}
private void inorderTraversal(Node<E> node) {
  // 結束條件
  if (node == null) return;

  // 訪問左子樹
  inorderTraversal(node.left, visitor);
  // 訪問根節點
  System.out.println(node.element);
  // 訪問右子樹
  inorderTraversal(node.right, visitor);
}

特別:中序遍歷是隻要保證根節點是在中間訪問,那麼先訪問左子樹還是先訪問右子樹,根據心情來決定就好。

後序遍歷

後序遍歷的順序是左子樹、右子樹,最後是根節點:

/**
 * 後序遍歷(遞歸)
 */
public void postorderTraversal() {
  preorderTanversal(root, visitor);
}
private void postorderTraversal(Node<E> node) {
  // 結束條件
  if (node == null) return;

  // 訪問左子樹
  postorderTraversal(node.left, visitor);
  // 訪問右子樹
  postorderTraversal(node.right, visitor);
  // 訪問根節點
  System.out.println(node.element);
}

層序遍歷

層序遍歷的訪問順序是從左到右,從上到下依次遍歷。那麼就可以通過隊列的方式去實現,在遍歷每一個節點的同時(出隊操作),將它的左右子節點依次入隊,直到隊列中的元素爲空,則遍歷就結束了。

/**
 * 層序遍歷
 */
public void leverOrderTraversal() {
  if (root == null) return;
  // 創建隊列
  Queue<Node<E>> queue = new LinkedList<>();

  // 第一節點入隊
  queue.offer(root);
  while (!queue.isEmpty()) {
    
    // 處理事件
    Node<E> node = queue.poll();
  	System.out.println(node.element);

    // 依次將存在的左右子樹入隊
    if (node.left != null) {
      queue.offer(node.left);
    }
    if (node.right != null) {
      queue.offer(node.right);
    }
  }
}

擴展

使用遞歸方式實現二叉樹的遍歷在代碼實現上是簡單的,關鍵要明白遞歸的思想和思路。建議在紙上去親自演算一下遞歸方式,會有利於理解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章