二分搜尋樹系列之[ 深度優先-層序遍歷 (ergodic) ]

yangkuang發表於2021-05-19

一.遍歷的分類

二分搜尋樹遍歷分為兩大類,深度優先遍歷和層序遍歷。
深度優先遍歷分為三種:先序遍歷(preorder tree walk)、中序遍歷(inorder tree walk)、後序遍歷(postorder tree walk),分別為:
1、前序遍歷:先訪問當前節點,再依次遞迴訪問左右子樹。
2、中序遍歷:先遞迴訪問左子樹,再訪問自身,再遞迴訪問右子樹。
3、後序遍歷:先遞迴訪問左右子樹,再訪問自身節點。

二. 深度優先遍歷

  • 前序遍歷:先訪問當前節點,再依次遞迴訪問左右子樹。
  • 中序遍歷:先遞迴訪問左子樹,再訪問自身,再遞迴訪問右子樹。
  • 後序遍歷:先遞迴訪問左右子樹,再訪問自身節點。
    為了更好理解深度優先遍歷我們使用下圖模型:

二分搜尋樹系列之【 深度優先-層序遍歷 (ergodic) 】

1. 前序遍歷:

我們對二分搜尋樹中所有節點都分別標記3個點:
二分搜尋樹系列之【 深度優先-層序遍歷 (ergodic) 】
開始遍歷:
前序遍歷是對每一個節點第一次訪問的時候進行遍歷:
28
二分搜尋樹系列之【 深度優先-層序遍歷 (ergodic) 】
遍歷:28, 16
二分搜尋樹系列之【 深度優先-層序遍歷 (ergodic) 】

遍歷:28, 16, 13
二分搜尋樹系列之【 深度優先-層序遍歷 (ergodic) 】

遍歷:28, 16, 13
二分搜尋樹系列之【 深度優先-層序遍歷 (ergodic) 】

遍歷:28, 16, 13
二分搜尋樹系列之【 深度優先-層序遍歷 (ergodic) 】

遍歷:28, 16, 13, 22
二分搜尋樹系列之【 深度優先-層序遍歷 (ergodic) 】

遍歷:28, 16, 13, 22
二分搜尋樹系列之【 深度優先-層序遍歷 (ergodic) 】

遍歷:28, 16, 13, 22
二分搜尋樹系列之【 深度優先-層序遍歷 (ergodic) 】

遍歷:28, 16, 13, 22
二分搜尋樹系列之【 深度優先-層序遍歷 (ergodic) 】

依次類推 ……

最後完成整個前序遍歷:

遍歷:28, 16, 13, 22, 30, 29, 42
二分搜尋樹系列之【 深度優先-層序遍歷 (ergodic) 】

**程式碼實現(使用遞迴,c++實現)
在public中定義:

//前序遍歷,傳入節點,列印節點相應資訊
void preOrder() {
    return preOrder(root);
}

在private中定義:

//前序遍歷,以node為根節點的二分搜尋樹進行前序遍歷,列印節點相應資訊
void preOrder(Node *node) {
    if (node != NULL) {
        //不一定用列印,還可以對node->key和node->value進行操作
  cout << node->key << endl;

  preOrder(node->left);

  preOrder(node->right);
  }
}
2. 中序遍歷

按照前序遍歷的模型和順序,很容易看出中序遍歷就是在中間點的時候進行遍歷:(過程省略)
遍歷:13, 16, 22, 28, 29, 30, 42
如下圖:(可以看出由中序遍歷可以看出遍歷結果是有序的)

二分搜尋樹系列之【 深度優先-層序遍歷 (ergodic) 】
**程式碼實現(使用遞迴,c++實現)
在public中定義:

//中序遍歷,以節點為node的節點為根節點
void inOrder() {
    return inOrder(root);
}

在private中定義:

//中序遍歷,以node為根節點的二分搜尋樹進行前序遍歷,列印節點相應資訊
void inOrder(Node *node) {
    if (node != NULL) {
        inOrder(node->left);

  cout << node->key << endl;

      inOrder(node->right);
  }
}
3. 後序遍歷

一樣的邏輯,後序遍歷就是在第三個點時進行遍歷:(過程省略)
遍歷:13, 22, 16, 29, 42, 30, 28
如下圖:
二分搜尋樹系列之【 深度優先-層序遍歷 (ergodic) 】
後序遍歷有個重要的應用:二叉樹的銷燬(從子節點依次向上刪除)

**程式碼實現(使用遞迴,c++實現)
在public中定義:

//後序遍歷,以node為根節點的二分搜尋樹進行前序遍歷,列印節點相應資訊
void postOrder() {
    return postOrder(root);
}

在private中定義:

//後序遍歷,以node為根節點的二分搜尋樹進行前序遍歷,列印節點相應資訊
void postOrder(Node *node) {
    if (node != NULL) {
        postOrder(node->left);

        postOrder(node->right);

  cout << node->key << endl;
  }
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章