學習筆記——二叉平衡樹(BST)

ylc666發表於2024-07-11

二叉平衡樹(BST)

BST 是一種資料結構,用於快速查詢資料。

二叉平衡樹有一個非常明顯的特性:對於每一個節點 \(u\),在其左邊的數都比它小,在其右邊待數都比它大。

每個點都有一個權值 cnt,用於儲存這個數出現了幾次。

在二叉平衡樹上的每一個操作的時間與其樹高成正比,約為 \(O(\log n)\)

BST的基本操作

插入

根據二叉平衡樹的性質,新加入的數分為以下幾種情況:

  • 比當前節點小,則將他下放到左兒子。
  • 等於這個節點,則將這個節點的 \(cnt+1\)
  • 否則則下放到右兒子。

最後如果沒有節點就新建一個節點,並且根據大小關係歸在父親節點的左或右兒子,將節點的 \(cnt\) 設為 \(1\)

刪除

和插入是相反操作,規則同插入操作,但當等於當前結點值的時候,要分兩種情況:

  • 當前結點的 \(cnt\)\(>1\),即當前節點存在不止一個數,直接將 \(cnt-1\) 即可。
  • 當前結點 \(cnt\)\(1\),即只有一個這樣的節點,這時候如果這個點是葉子節點(下面沒有兒子,直接將這個點的 \(cnt\) 設成 \(0\),編號直接刪除。如果這個節點下面還有兒子,就把下面兩個元素中的任意一個元素所有變數賦值到這個位置,並且遞迴刪除下面的點,操作同上。

查詢排名為 \(x\) 的元素

根節點的排名取決於左子樹的大小。

  • 當左子樹大小大於等於 \(x\),則這個元素位於左子樹
  • 當左子樹大小位於 \([x-cnt, x-1]\) 之間,則這個元素位於根節點
  • 否則,這個元素位於右子樹

查詢元素 \(x\) 的排名

相當於搜尋 \(x\),在遍歷右子樹時需要加上左子樹以及根節點的大小。

BST 的時間複雜度約為 \(O(\log n)\),但是由於其特殊的性質,最壞情況下可以退化成一條鏈,這時候,複雜度將會退化成 \(O(n)\),有超時風險。這時候就需要最佳化,最佳化方法有 Treap 和 Splay 等。

相關文章