【高階數據結構】B-數、B+樹、B*樹的原理

文章目錄

  • B樹的概念及其特點
  • 解析B樹的基本操作
    • 插入數據
      • 插入數據模擬
    • 分析分裂如何維護平衡性
    • 分析B樹的性能
  • B+樹和B*樹
    • B+樹
      • B+樹的分裂
      • B+樹的優勢
    • B*
      • B*樹的分裂
  • 總結

B樹的概念及其特點

B樹是一顆多叉的平衡搜索樹,廣泛應用于數據庫和 文件系統中,以保持數據有序并允許高效的插入、刪除和查找操作。下面介紹B樹的特點:

  • 多路平衡樹:多路平衡樹其實就是多叉平衡樹每個節點都有多個指向孩子節點的指針以及鍵值。通常,一顆m階的B樹有k個子節點,有k-1個關鍵字,而k的取值范圍為[ceil(m/2),m](celi表示向上取整)。例如一顆3階的B樹,最多有3個孩子2個關鍵字。
  • 鍵值有序:每個節點中包含多個關鍵字,這些關鍵字是有序的。節點中每個關鍵字都將子節點切割成兩部分,左邊部分的節點的所有關鍵字的值一定是小于該關鍵字的,右邊節點的所有關鍵字的值都是大于該關鍵字的,這一點跟二叉搜索樹的性質相同。
  • 樹的高度平衡:所有葉子節點的深度都是一樣的,站在AVL樹的角度講,每個節點的平衡因子都是0。具體如何維護這個平衡性下面會詳細介紹。
  • 高效的磁盤讀寫:B樹被設計用于在磁盤上高效的存儲和讀取數據。通過每個節點都有多個鍵值和多個字節的指針,從而減少磁盤的讀寫次數

下面給出一個3階B樹的節點示意圖:
在這里插入圖片描述
在設計B樹節點時,孩子數量通常要多一個,這是為了方便后續實現插入操作和刪除操作。概念上我們依舊認為m階B樹的節點的孩子個數為k個,實現的時候認為是k+1個。
我們將一個節點的所有鍵值集合稱為數據域

解析B樹的基本操作

插入數據

為了保證插入節點之后B樹保持其平衡性,我們采用分裂節點來保持樹的結構。具體的插入步驟如下:

  1. 查找插入位置:首先從根節點開始,找到應該插入新鍵值的葉子節點。(B樹每一次插入新鍵值都一定在葉子節點處)
  2. 插入鍵值:在找到的葉子節點處插入新鍵值。如果該葉子節點的鍵值已經滿了,即關鍵字的個數等于m+1,則需要對該葉子節點進行分裂。分裂的操作步驟如下:
    • 找到節點數據域的中間位置
    • 給一個新節點,將中間位置右邊的所有數據(包括鍵值和孩子指針)搬到新節點中。新節點是被分裂節點的兄弟節點。
    • 將中間位置的鍵值移動放到父親節點中,如果沒有父節點,那就再創建一個父節點,并連接。

插入數據模擬

現在假設我們有一顆階數為3的B樹(每個節點最多有3個孩子和2個鍵值),并按以下順序插入鍵值:10, 20, 5, 6, 12, 30, 7, 17。

  • 當插入了10、20之后:
    在這里插入圖片描述
    只有一個節點,該節點已經有兩個鍵值分別是10、20,現在這個節點的鍵值已經滿了。
  • 插入5,節點鍵值溢出需要分裂:
    在這里插入圖片描述
    仔細觀察上述結果,根據插入數據的步驟,插入節點的鍵值滿了,需要分裂。找到數據域的中間位置,也就是10的位置,10右邊的數據全部移動到新兄弟節點中,再把中間鍵值10提取出來插入到父親節點中。由于沒有父節點,則新創建一個父節點。

點擊觀看分裂演示過程
點擊觀看整個插入過程

分析分裂如何維護平衡性

為什么分裂操作會保證B-樹維持特性呢?以下是具體分析:

  • 保證葉子節點在同一深度:分裂只是在滿節點的基礎上進行的,將中間鍵提升到父節點并不會改變葉子節點的深度差,如果父節點滿了,那父節點再分裂。如果父節點不存在,那么就會創建一個新父節點,此時這個新父節點一定成為了B樹的根節點,也就意味著每條葉子節點分支的高度都會+1。
  • 控制節點的鍵值數量:每次分裂出去的鍵值數量都是大約一半,新的兄弟節點擁有的鍵值數量和被分裂節點的鍵值數量幾乎一致。這樣就保證了B樹每個節點的鍵值數目在[ceil(m/2)?1,m?1]之間。
  • 分裂后有序:由于中間鍵值的選擇,新的兄弟節點的所有鍵值一定都大于被分裂節點剩下的鍵值。再將中間鍵值插入到父節點中,中間鍵的左孩子指向被分裂節點,右孩子指向新兄弟節點,這樣一來,整顆樹還是一顆搜索樹。

分析B樹的性能

設n為B樹的總鍵值數量,m為B樹的階數。則每個節點最多有m個孩子節點,m-1個關鍵字。

  • 查找效率:查找操作在B樹中的時間復雜度為O(log n),原因如下:

    • B樹的高度h和節點的最小度數t以及總鍵值數n的關系為:h=logt(n),因為每個節點至少有t個子節點。
    • 在每個節點中查找特定鍵值的時間復雜度為O(t),但由于t是一個常數,所以總時間復雜度就是O(1)。(t是B樹的最小度數ceil(m/2),是確定的)
    • 查找的總時間效率就是樹的高度乘每個節點查找特定鍵值的時間,也就是O(log n)
  • 插入操作:插入操作的時間復雜度也是O(log n),具體分析如下

    • 查找到插入位置的時間復雜度為O(logn)
    • 插入后可能需要分裂節點,分裂操作的時間復雜度為O(t),這是因為每個節點最多包含t個鍵值。
    • 由于樹的高度較小且分裂操作是局部的,整體插入操作的時間復雜度仍為O(log n)。
  • 刪除操作:刪除操作的時間復雜度也是O(log n),具體分析:

    • 查找到目標節點的時間復雜度為O(log n)
    • 刪除操作可能涉及節點的合并或鍵值的重新分配,這些操作的時間復雜度都是O(t),同樣由于t是常數,總體的時間復雜度還是O(log n)

綜上,B樹各種操作時間效率都是logn。下面分析B樹的空間復雜度:
B樹的空間復雜度主要受到節點數目的影響。每個節點包含k-1個鍵值和k+1個子節點指針,節點總數與樹的高度和階數有關。由于B樹是多路平衡樹,其空間復雜度可以表示為O(n),其中n是鍵值總數。

B+樹和B*樹

B+樹

B+樹是B樹的變形,在B樹的基礎上優化的多路平衡樹,B+樹的規則和B樹類似,但在B樹的基礎上做了以下幾點改進優化:

  • 分支節點的子節點指針數量和關鍵字的個數相同(或者是子節點數量比關鍵字個數多1)
  • 分支節點不存儲實際的數據,只用于引導查找路徑(存儲的是孩子節點的最小關鍵字)
  • 所有的實際數據都存在葉子節點中
  • 葉子節點按照鍵值排序,彼此之間用一個指針連接,形成一個鏈表

下面給出一顆B+樹結構示意圖:
在這里插入圖片描述
在B+樹中如何查找一個數據呢?步驟如下:

和B樹一致,從根節點開始逐層向下查找,比較當前鍵值和目標鍵值,如果大于目標鍵值,說明當前鍵值的孩子分支的所有值都大于目標鍵值。所以我們需要找到一個第一個大于目標鍵值的前一個鍵值種去尋找。點擊演示B+樹插入數據的動畫。

B+樹的分裂

當一個結點滿時,分配一個新的結點,并將原結點中1/2的數據復制到新結點,最后在父結點中增加新結點的指針;B+樹的分裂只影響原結點和父結點,而不會影響兄弟結點,所以它不需要指向兄弟的指針。

時間復雜度和空間復雜度和B數一樣。

B+樹的優勢

  • 范圍查詢非常高效,因為葉子節點通過鏈表連接,可以順序訪問所有滿足范圍條件的節點。范圍查詢性能優于B樹
  • 插入和刪除操作相對簡單一些,因為數據只存儲在葉子節點中,只需在葉子節點中維護平衡
  • B+樹適用于高效訪問和順序訪問的場景

B*

B*樹是B+樹的變形,在B+樹的非根和非葉子節點再增加指向兄弟節點的指針。具體結構如下:
在這里插入圖片描述

B*樹的分裂

當一個結點滿時,如果它的下一個兄弟結點未滿,那么將一部分數據移到兄弟結點中,再在原結點插入關鍵字,最后修改父結點中兄弟結點的關鍵字(因為兄弟結點的關鍵字范圍改變了);如果兄弟也滿了,則在原結點與兄弟結點之間增加新結點,并各復制1/3的數據到新結點,最后在父結點增加新結點的指針。所以,B*樹分配新結點的概率比B+樹要低,空間使用率更高

總結

  • B樹:有序數組+平衡多叉樹
  • B+樹:有序數組鏈表+平衡多叉樹
  • B*樹:一棵更豐滿的,空間利用率更高的B+樹

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/41048.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/41048.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/41048.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

等保2.0的具體技術要求有哪些重點?

在數字化浪潮洶涌澎湃的當下,網絡安全猶如一座守護智慧之城的巍峨城墻,不可或缺。等級保護制度(等保)作為我國網絡安全戰略的基石,歷經歲月沉淀,已演進至2.0時代,即《網絡安全等級保護基本要求》…

算法思想總結:優先級隊列

一、最后一塊石頭的重量 . - 力扣(LeetCode) 我們每次都要快速找到前兩個最大的石頭進行抵消,這個時候用優先級隊列(建大堆),不斷取堆頂元素是最好的!每次刪除堆頂元素后,可以自動調整&#xf…

CentOS 7配置阿里云鏡像源及其加速

備份原yum源的配置:mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 下載Centos-7.repo文件curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo 清除及生成緩存 # 清除yum緩存 yum clean …

HarmonyOS - 通過.p7b文件獲取fingerprint

1、查詢工程所對應的 .p7b 文件 通常新工程運行按照需要通過 DevEco Studio 的 Project Structure 勾選 Automatically generate signature 自動生成簽名文件,自動生成的 .p7b 文件通常默認在系統用戶目錄下. 如:C:/Users/zhangsan/.ohos/config/default…

【Thread】python Thread Timer使用示例

import threading import time# 定義一個函數,它接受可變數量的字符串參數 def print_message(*messages):for message in messages:print(message)# 定義一個函數,它作為定時器線程的回調函數 def timer_thread(wait_time, *args):print(f"等待 {w…

JavaSE面試題(二)

目錄 一.為什么會有Java內存模型? 二.什么樣的情況下finally不會執行 三.鉤子是什么? 四.編譯時期的多態性和運行時期的多態性 五.談談反射機制 六.Java管道 本專欄全是博主自己收集的面試題,僅可參考,不能相信面試官就出這…

TCP報文校驗和(checksum)計算

一. 原理 將TCP相關內容&#xff08;TCP偽頭部TCP頭部TCP內容&#xff09;轉換成16比特的字符&#xff0c;然后進行累加&#xff0c;最后結果進行取反。TCP偽頭部是固定的&#xff0c;下文有相關代碼展示。 二. 源碼 源碼 #include <stdio.h> #include <stdlib.h&…

3D雞哥又上開源項目!單圖即可生成,在線可玩

大家好&#xff0c;今天和大家分享幾篇最新的工作 1、Unique3D Unique3D從單視圖圖像高效生成高質量3D網格&#xff0c;具有SOTA水平的保真度和強大的通用性。 如下圖所示 Unique3D 在 30 秒內從單視圖野生圖像生成高保真且多樣化的紋理網格。 例如屬于一張雞哥的打球寫真照 等…

js 遞歸調用 相同對象--數組遞歸調用

<div class="save-cl"> <a-button @click="saveCl" >保存為常用策略</a-button> </div> saveCl(){ console.log(this.form.filterList[0],--------常用策略)// 此對象為上圖對象 console.log(this.allElementsHaveValue(thi…

Windows的管理工具

任務計劃程序&#xff1a;這是一個用來安排任務自動運行的工具。你可以在這里創建新的任務&#xff0c;設定觸發條件&#xff0c;并指定任務的操作。 事件查看器&#xff1a;這是一套日志記錄和分析工具&#xff0c;&#xff0c;你可以了解到系統的工作狀況&#xff0c;幫助診…

損失函數篇

損失函數 1、邊界框損失函數/回歸損失函數bbox_loss 2、分類損失函數cls_loss 3、置信度損失函數obj_loss YOLOv8損失函數 1、概述 通過YOLOv8-訓練流程-正負樣本分配的介紹&#xff0c;我們可以知道&#xff0c;經過預處理與篩選的過程得到最終的訓練數據&#xff1a; a…

微信小程序/uniapp:class和style不生效的問題

非常重要&#xff1a;小程序端不支持 classObject 和 styleObject 語法。 文檔&#xff1a;https://uniapp.dcloud.net.cn/tutorial/vue-basics.html#class-與-style-綁定 目錄 對象語法數組語法字符串語法computed其他方案 對象語法 <!-- class --> <view class&quo…

AI是在幫助開發者還是取代它們?

在這個科技日新月異的時代&#xff0c;人工智能&#xff08;AI&#xff09;已經滲透到了我們生活的方方面面&#xff0c;尤其是在軟件開發和編程領域&#xff0c;其影響更是深遠。AI技術的飛速發展引發了廣泛討論&#xff1a;它究竟是開發者們的得力助手&#xff0c;還是未來可…

2024 年最佳 Figma 字體

字體不僅僅是文本字符&#xff0c;它們還塑造了用戶體驗。從引導用戶瀏覽界面到傳達品牌個性&#xff0c;字體對于設計??至關重要。然而&#xff0c;找到適合您的網站或應用風格的完美字體可能具有挑戰性。 但不要害怕&#xff0c;我們會幫助您&#xff01;請繼續關注&#x…

C語言 指針和數組——指針的算術運算

目錄 指針的算術運算 指針加上一個整數 指針減去一個整數 指針相減 指針的關系比較運算 小結 指針的算術運算 指針加上一個整數 指針減去一個整數 指針相減 指針的關系比較運算 小結 ? 指針變量 – 指針類型的變量&#xff0c;保存地址型數據 ? 指針變量與其他類型…

負載均衡(服務器)

vi /etc/sysconfig/network-scripts/ifcfg-ens33 systemctl restart network 防火墻 systemctl stop firewalld systemctl disable firewalld vi /etc/selinux/config setenforce 0 yum install gcc gcc-c mkdir /lnmp cd /lnmp/ tar -zxvf zlib-1.2.12.tar.gz tar -zxv…

在Ubuntu 16.04上安裝和配置ownCloud的方法

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到網站。 簡介 ownCloud 是一個文件共享服務器&#xff0c;允許您將個人內容&#xff08;如文檔和圖片&#xff09;存儲在一個類似 Dropbox 的集…

[C++][CMake][CMake基礎]詳細講解

目錄 1.CMake簡介2.大小寫&#xff1f;3.注釋1.注釋行2.注釋塊 4.日志 1.CMake簡介 CMake是一個項目構建工具&#xff0c;并且是跨平臺的 問題 – 解決 如果自己動手寫Makefile&#xff0c;會發現&#xff0c;Makefile通常依賴于當前的編譯平臺&#xff0c;而且編寫Makefile的…

vue的學習--day3

1、嘗試使用json文件模擬增刪改查 json server:準備一份自己的數據&#xff08;這里我用的是老師給的&#xff09;。 轉到d盤&#xff0c;然后打開json文件&#xff1a; 下面模擬增刪改查&#xff1a; 借助工具postman或apifox或apipost&#xff1a; 這里我下載了apifox&…

前端之CSS篇--面試題總結

CSS的特性&#xff1a;繼承性、層疊性、優先級 優先級&#xff1a;寫css樣式的時候&#xff0c;會給同一個元素添加多個樣式&#xff0c;此時誰的權重搞就顯示誰的樣式。 !important >行內樣式>id>類>標簽>全局選擇器 隱藏元素的方法 display:none 元素在頁面…