B樹,B+樹,B*樹

下面我們來詳細講解一下?B樹、B+樹、B*樹?這三種非常重要的多路平衡查找樹。它們在數據庫和文件系統中有著極其廣泛的應用。


一、為什么需要這些樹結構?

在開始之前,我們先思考一個問題:為什么已經有了二叉搜索樹(BST)、AVL樹、紅黑樹,還需要B樹家族?

答案是:磁盤I/O

  • 內存訪問:速度極快,納秒級別。
  • 磁盤訪問:速度極慢,毫秒級別,比內存慢了幾個數量級。

操作系統從磁盤讀取數據時,并不是按需一個字節一個字節地讀,而是以(Page,通常為4KB或8KB)為單位進行預讀。一次I/O操作會把一整頁的數據都加載到內存中。

傳統的二叉樹(如紅黑樹)雖然內存中效率很高,但每個節點只存儲少量數據,如果數據量巨大,樹會變得很高。查詢一個數據可能需要從根節點訪問到葉子節點,這期間可能發生很多次磁盤I/O(因為節點可能不在同一頁),性能會急劇下降。

B樹家族的設計目標就是為了減少磁盤I/O次數。它們的核心思想是:

一個節點 = 一個磁盤頁

通過在每個節點中存儲更多的鍵和指針,讓樹變得更“矮胖”,從而降低樹的高度,減少查詢時的I/O次數。


二、B樹 (B-Tree)

B樹是一種自平衡的多路搜索樹,它不是二叉的,一個節點可以有多個子節點。

1. 結構特點
  • 平衡性:所有葉子節點都位于同一層,保證了查詢性能的穩定。
  • 多路性:一個節點可以擁有多于兩個的子節點。這通常用“階”(m)來定義。一棵m階的B樹滿足以下條件:
    • 每個節點最多有?m?個子節點。
    • 除根節點和葉子節點外,每個節點至少有?ceil(m/2)?個子節點(ceil是向上取整)。
    • 根節點至少有2個子節點(除非它同時也是葉子節點)。
    • 所有葉子節點都在同一層。
    • 一個有?k?個子節點的非葉子節點,包含?k-1?個鍵(Key)。
    • 節點中的鍵是有序的。
2. 節點結構

一個典型的B樹節點包含:

  • n?個鍵?K?, K?, ..., K?
  • n+1?個指針?P?, P?, ..., P?
  • 指針指向子節點,鍵和指針的排列滿足:P?指向的子樹中所有鍵 <?K??<?P?指向的子樹中所有鍵 <?K??< … <?K??<?P?指向的子樹中所有鍵。

示例(3階B樹,也叫2-3樹):

        [ 20 | 40 ]/     |     \[10, 15] [30, 35] [50, 60]
  • 每個節點最多有3個子節點,至少有2個子節點。
  • 每個節點最多有2個鍵,至少有1個鍵。
3. 操作
  • 查找:從根節點開始,將待查找的鍵與節點中的鍵比較,確定下一步要進入哪個子樹,直到找到或到達葉子節點。
  • 插入:找到合適的葉子節點插入。如果插入后節點鍵的數量超過?m-1,則節點分裂。中間的鍵向上提升到父節點,如果父節點也滿了,則繼續向上分裂,可能一直到根節點。
  • 刪除:比較復雜,可能需要從兄弟節點“借”鍵,或者與兄弟節點合并,甚至可能導致父節點的合并,是一個遞歸的過程。
4. 優缺點
  • 優點
    • 矮胖,樹的高度低,I/O次數少,非常適合磁盤存儲。
    • 查詢、插入、刪除的時間復雜度都為?O(log?N),其中N是鍵的數量,m是階數。
  • 缺點
    • 每個節點都存儲了鍵和數據(如果數據很大,節點能存的鍵就變少了,樹會變高)。
    • 范圍查詢效率不高,因為數據分散在所有節點中,需要進行中序遍歷,這會涉及大量的隨機I/O。

三、B+樹 (B+ Tree)

B+樹是B樹的變種,也是目前數據庫索引中最常用的數據結構(如MySQL的InnoDB引擎)。它對B樹做了優化,使其更適合范圍查詢和全表掃描。

1. 結構特點(與B樹的區別)

B+樹在B樹的基礎上增加了以下特性:

  • 數據只在葉子節點
    • 非葉子節點(索引節點):只存儲鍵和指向子節點的指針,不存儲數據。這使得非葉子節點可以存儲更多的鍵,樹的結構更“矮胖”,I/O效率更高。
    • 葉子節點(數據節點):存儲了所有的鍵和對應的數據。
  • 葉子節點形成有序鏈表
    • 所有的葉子節點通過指針連接成一個雙向有序鏈表
    • 這使得范圍查詢變得極其高效,只需定位到范圍的起始點,然后沿著鏈表順序遍歷即可,幾乎都是順序I/O。
  • 查詢效率更穩定
    • 任何查詢都必須從根節點走到葉子節點才能獲取到數據。而B樹可能在非葉子節點就命中數據。這使得B+樹的每次查詢的I/O次數更加穩定。
2. 圖示
        [ 20 | 40 ]/     |     \[ 10 ]   [ 30 ]   [ 50 ]/         |         \
[10, Data] [30, Data] [50, Data]<--------> <--------> <--------> (雙向鏈表)
  • 上面的非葉子節點只做索引,不存數據。
  • 下面的葉子節點存數據,并且用鏈表連接。
3. 優缺點
  • 優點
    • 更矮胖:由于非葉子節點不存數據,能容納更多鍵,樹高更低,I/O次數更少。
    • 查詢性能穩定:每次查詢都必須查到葉子節點,性能穩定。
    • 范圍查詢極其高效:葉子節點的有序鏈表結構,使得范圍查詢和排序操作非常快。
    • 全表掃描快:只需遍歷葉子節點的鏈表即可。
  • 缺點
    • 單點查詢(根據主鍵查一條記錄)可能比B樹稍慢,因為B樹可能在非葉子節點就找到數據,而B+樹必須走到葉子節點。但在實際應用中,由于B+樹更矮胖,這個劣勢通常不明顯,甚至可能更快。

四、B*樹 (B* Tree)

B*樹是B樹的另一個變種,它的目標是進一步提高節點的空間利用率

1. 結構特點(與B樹的區別)

B*樹的核心思想是增加節點的填充率,從而減少節點分裂的頻率。

  • 更高的填充因子
    • B樹要求每個非根、非葉節點至少半滿(ceil(m/2))。
    • B*樹要求每個非根、非葉節點至少?2/3滿ceil(2m/3))。
  • 獨特的分裂策略
    • 當一個節點滿了需要插入新數據時,B*樹不會立即分裂
    • 它會先檢查其相鄰的兄弟節點是否還有空間。
    • 如果兄弟節點未滿:將當前節點和兄弟節點的鍵重新分配,讓兩個節點都達到2/3滿。這個過程稱為節點重分配
    • 如果兄弟節點也滿了:才會進行分裂。但B*樹的分裂也與B樹不同。它不是將一個節點分成兩個,而是將當前節點和它的一個兄弟節點一起分裂成三個節點,并保證這三個節點都是2/3滿的。
2. 優缺點
  • 優點
    • 極高的空間利用率:由于2/3的填充因子和延遲分裂策略,節點的空間利用率非常高,浪費的空間很少。
    • 更少的分裂操作:節點重分配和“分裂成三”的策略大大降低了節點分裂的頻率,從而減少了I/O操作,提高了插入性能。
  • 缺點
    • 實現復雜:插入和刪除的邏輯比B樹和B+樹復雜得多,需要處理節點重分配和復雜的分裂邏輯。
    • 應用較少:由于其復雜性,B*樹在實際應用中不如B+樹普及。但在一些對空間利用率和插入性能要求極高的文件系統中,可能會看到它的身影。

總結與對比

特性B樹B+樹B*樹
數據存儲位置所有節點(鍵+數據)僅葉子節點(鍵+數據)僅葉子節點(鍵+數據)
非葉子節點作用索引+數據僅索引僅索引
葉子節點結構獨立,無連接雙向有序鏈表雙向有序鏈表
查詢性能不穩定(可能在非葉子節點命中)穩定(必須到葉子節點)穩定(必須到葉子節點)
范圍查詢效率低(中序遍歷,隨機I/O)效率極高(鏈表順序遍歷)效率極高(鏈表順序遍歷)
節點填充率至少半滿 (ceil(m/2))至少半滿 (ceil(m/2))至少2/3滿?(ceil(2m/3))
分裂策略節點滿則分裂成兩個節點滿則分裂成兩個先嘗試與兄弟節點重分配,失敗則分裂成三個
空間利用率一般較高非常高
實現復雜度中等中等
主要應用文件系統(如HFS+, NTFS部分)數據庫索引(MySQL, Oracle)少數文件系統,對空間利用率要求高的場景

一句話總結

  • B樹:是“矮胖”的多路樹,解決了磁盤I/O問題,但數據分散,不適合范圍查詢。
  • B+樹:在B樹基礎上,將數據全部移到葉子節點并用鏈表連接,完美優化了范圍查詢,成為數據庫索引的事實標準
  • B*樹:在B樹基礎上,通過提高填充率和改進分裂策略,極致地優化了空間利用率和插入性能,但實現復雜,應用較少。

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

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

相關文章

汽車零部件工廠ESOP系統工業一體機如何選型

在汽車零部件工廠的生產管理中&#xff0c;ESOP 系統發揮著至關重要的作用。而工業一體機作為 ESOP 系統的關鍵硬件支撐&#xff0c;其選型的合理性直接關系到生產效率的提升、生產過程的精準控制以及生產數據的可靠采集與分析。因此&#xff0c;為汽車零部件工廠選擇一款適合的…

?維基框架 (Wiki Framework) 1.1.0 版本發布? 提供多模型AI輔助開發

介紹 多模型AI輔助開發? 維基框架1.1.0集成了主流AI引擎的統一接口&#xff0c;支持開發者按需調用不同模型的優勢能力&#xff1a; ?DeepSeek?&#xff1a;專注代碼生成與重構&#xff0c;擅長復雜業務邏輯實現 ?ChatGPT?&#xff1a;多模態推理能力&#xff0c;適用于…

LabVIEW調用MATLAB 的分形生成

LabVIEW 調用 MATLAB&#xff0c;可借前者可視化流程與硬件交互優勢&#xff0c;結合后者強數值計算、算法能力&#xff0c;復用成熟算法提速開發&#xff0c;還能靈活改代碼。但需匹配版本、裝運行環境&#xff0c;數據傳遞有性能損耗&#xff0c;腳本出錯需跨軟件調試。?優點…

ubuntu20.04開發ros2,使用docker安裝部署的詳細教程

學習docker的教程&#xff1a;可以直接在菜鳥教程上學習即可階段 0&#xff1a;系統檢查| 內容 | 建議 | |------|------| | 操作系統 | Ubuntu 22.04&#xff08;與 ROS2 Humble 最匹配&#xff09; | | 用戶權限 | 能執行 sudo |&#x1f9e9; 階段 1&#xff1a;在 Ubuntu 上…

SQL Server縮小日志文件.ldf的方法(適用于開發環境)

SQL Server縮小日志文件.ldf的方法&#xff08;適用于開發環境&#xff09; 核心概念&#xff1a;為什么日志文件會變大&#xff1f; 首先&#xff0c;理解原因至關重要。事務日志文件在以下情況下會增長&#xff1a; 大量操作&#xff1a;執行了大批量插入、更新或刪除操作&am…

2.3零基礎玩轉uni-app輪播圖:從入門到精通 (咸蝦米總結)

還在uni-app中的輪播圖組件頭疼嗎&#xff1f;看完這篇&#xff0c;讓你輕松掌握swiper的所有秘密&#xff01;輪播圖的重要性 在現代移動應用開發中&#xff0c;輪播圖&#xff08;Swiper&#xff09;已成為展示焦點內容、廣告推廣和產品展示的首選組件。無論是電商平臺的商品…

FPGA學習筆記——AHT20溫濕度讀取并在串口顯示(IIC協議)

目錄 一、任務 二、分析 1.需要了解的 2.需要用到的模塊 3.流程分析 三、Visio圖 四、代碼 五、實驗現象 一、任務 使用IIC協議通信的AHT20&#xff0c;將溫濕度數據讀取出來&#xff0c;并在串口助手上顯示。 二、分析 1.需要了解的 需要了解IIC協議簡介 也可以看看E…

Pycharm SSH連接

添加遠程服務器文件——>設置——>項目下的Python解釋器——>添加解釋器——>SSH在彈出的彈窗中&#xff0c;輸入遠程的主機、端口和用戶名、一直下一步&#xff0c;得到如下圖所示的結果&#xff1a;選擇Conda 環境&#xff1a;第一步選擇Conda環境&#xff1b;第…

c# 讀取xml文件內的數據

好多大型的項目&#xff0c;把一些固定的參數都存在 xml文件里。創建c# winfom 項目&#xff0c;test_xml創建resources文件夾存放xml文件創建parameters.xml文件<root><test_xml><param name "threshold" value "128"/><param name …

Legion Y7000P IRX9 DriveList

Legion Y7000P IRX9 DriveList 聯想Y7000P驅動列表 驅動列表 intelwlan-TYY5057FK6MQBRF0.exe NVVGA-TYY5057F3M0H9RF0.exe RTKwlan-TYY5077FFSNECRF0.exe audio-TYY5057F4N1JARF0.exe chipset-TYY5037FB10X3RF0.exe hdr-TYY5027FXNF9AWF0.exe intelVGA-TYY5057F5R9J7RF…

編程與數學 02-017 Python 面向對象編程 23課題、測試面向對象的程序

編程與數學 02-017 Python 面向對象編程 23課題、測試面向對象的程序一、單元測試&#xff08;Unit Testing&#xff09;使用 unittest 模塊使用 pytest二、集成測試&#xff08;Integration Testing&#xff09;三、模擬對象&#xff08;Mocking&#xff09;四、測試驅動開發&…

[React]Antd Cascader組件地區選擇

前言表單中添加一個地區選擇功能&#xff0c;要求支持增刪改查功能。Cascader 使用Cascader組件動態加載地區選項。使用 loadData 實現動態加載選項&#xff0c;&#xff08;loadData 與 showSearch 無法一起使用&#xff09;。 這里使用了Form.Item組件。 <Form.Itemlabel{…

深度學習-----《PyTorch神經網絡高效訓練與測試:優化器對比、激活函數優化及實戰技巧》

一、訓練過程并行批量訓練機制一次性輸入64個批次數據&#xff0c;創建64個獨立神經網絡并行訓練。所有網絡共享參數&#xff08;Ω&#xff09;&#xff0c;更新時計算64個批次的平均損失&#xff0c;統一更新全局參數。梯度更新策略使用torch.no_grad()上下文管理器清理反向傳…

Matplotlib 可視化大師系列(五):plt.pie() - 展示組成部分的餅圖

目錄Matplotlib 可視化大師系列博客總覽Matplotlib 可視化大師系列&#xff08;五&#xff09;&#xff1a;plt.pie() - 展示組成部分的餅圖一、 餅圖是什么&#xff1f;何時使用&#xff08;何時避免&#xff09;&#xff1f;二、 函數原型與核心參數三、 從入門到精通&#x…

C++ Core Guidelines 核心理念

引言 C 是一門功能強大但復雜性極高的編程語言。為了幫助開發者更高效、安全地使用現代 C&#xff0c;C 核心指南&#xff08;CppCoreGuidelines&#xff09;應運而生。這份由 C 之父 Bjarne Stroustrup 等人主導的指南&#xff0c;提供了大量關于 C 編碼的規則、最佳實踐和設…

vue3 - 組件間的傳值

組件間傳參 父傳子v-on/props 父組件使用v-on:綁定要傳的參數:parentData"parentData"&#xff1a; <template><div><Child1 :parentData"parentData"></Child1></div> </template> <script setup lang"ts…

Kafka 在 6 大典型用例的落地實踐架構、參數與避坑清單

一、選型速查表場景關鍵目標推薦清單&#xff08;示例&#xff09;消息&#xff08;Messaging&#xff09;解耦、低延遲、可靠投遞acksall、enable.idempotencetrue、retries>0、min.insync.replicas2、合理分區鍵、DLT網站活動追蹤吞吐極高、可回放主題按類型拆分&#xff…

Node.js(1)—— Node.js介紹與入門

前面我們談到一些前端開發的內容&#xff0c;學習了HTML、css和JavaScript&#xff0c;已經掌握了如何編寫一些簡單功能的網頁。但是只屬于前端部分&#xff0c;我們只能在本地打開文件進行瀏覽&#xff0c;不能讓其他人打開我們編寫的網站&#xff1b;這時就需要后端部分上場了…

Python辦公——爬蟲百度翻譯網頁版(自制翻譯小工具——進階更新版)

目錄 專欄導讀 前言 項目概述 功能特點 技術棧 核心架構設計 類結構設計 界面布局設計 核心功能實現 1. 智能語言檢測 2. 異步翻譯處理 3. HTTP請求處理 4. 結果解析與顯示 界面設計亮點 1. 響應式布局 2. 用戶體驗優化 3. 現代化組件 技術難點與解決方案 1. 跨線程UI更新 2. U…