五分鐘搞懂什麼是B-樹(全程圖解)【轉】

来源:https://www.cnblogs.com/linhaostudy/archive/2019/09/10/11497320.html
-Advertisement-
Play Games

前戲 我們大家都知道動態查找樹能夠提高查找效率,比如:二叉查找樹,平衡二叉查找樹,紅黑樹。他們查找效率的時間複雜度O(log2n),跟樹的深度有關係,那麼怎麼樣才能提高效率呢?當然最快捷的方式就是減少樹的深度了。那麼怎麼減少樹的深度呢?為瞭解答這個問題,我們慢慢來看,先看個實際問題吧。 問題背景 在 ...


前戲

我們大家都知道動態查找樹能夠提高查找效率,比如:二叉查找樹,平衡二叉查找樹,紅黑樹。他們查找效率的時間複雜度O(log2n),跟樹的深度有關係,那麼怎麼樣才能提高效率呢?當然最快捷的方式就是減少樹的深度了。那麼怎麼減少樹的深度呢?為瞭解答這個問題,我們慢慢來看,先看個實際問題吧。

問題背景

在大型的資料庫存儲中,實現索引查找,如果採用二叉查找樹的查找的話,由於節點的存儲數據是有限的(不可能將節點存儲過多的數據,否則就變成線性的查找了),這樣如果數據量很大的,就會導致樹的深度過大從而造成磁碟IO操作過於頻繁(你們知道磁碟IO操作是非常耗時的),就會導致效率非常低下。可能有童鞋會問了,那為什麼不把節點索引載入到記憶體中,這樣訪問不就快了嗎?其實這顯然是不可能完成的,因為往往存儲的索引可能就有好幾個G了。全部載入到記憶體也是不現實的。能做的只有逐一載入每一個磁碟頁,這裡的磁碟頁就相當於索引樹的節點。

根據平衡二叉樹的啟發,自然就想到了平衡多路查找樹結構。也就是本文的主題B-tree,好了廢話不多說了,進入正題!

B-tree的簡介

B-樹就是我們平常說的B樹,不要讀成B減樹了,它在文件系統中很有用(原因之前已經介紹了),我們先來看下一個m階的Bs樹具有如下幾個特性:

  • 根節點至少有兩個子女
  • 每個中間節點都包含k-1個元素和k個孩子,其中m/2<=k<=m
  • 每個葉子節點都包含k-1元素,其中m/2<=k<=m
  • 所有的葉子節點都位於同一層

每個節點的元素從小到大排列,節點當中k-1個元素正好是k個孩子包含的元素的值域分劃。

看起來是不是很複雜,沒看懂也沒有關係,我們用實際例子來演示下。例子來源網路,參考:

https://blog.csdn.net/qq_35644234/article/details/66969238

B-樹插入

其實B-樹的插入是很簡單的,它主要是分為如下的兩個步驟:

 1. 使用之前介紹的查找演算法查找出關鍵字的插入位置,如果我們在B-樹中查找到了關鍵字,則直接返回。否則它一定會失敗在某個最底層的終端結點上。
 2.然後,我就需要判斷那個終端結點上的關鍵字數量是否滿足:n<=m-1,如果滿足的話,就直接在該終端結點上添加一個關鍵字,否則我們就需要產生結點的“分裂”。
分裂的方法是:生成一新結點。把原結點上的關鍵字和k(需要插入的值)按升序排序後,從中間位置把關鍵字(不包括中間位置的關鍵字)分成兩部分。左部分所含關鍵字放在舊結點中,右部分所含關鍵字放在新結點中,中間位置的關鍵字連同新結點的存儲位置插入到父結點中。如果父結點的關鍵字個數也超過(m-1),則要再分裂,再往上插。直至這個過程傳到根結點為止。

一個原始的B-樹階為3,如下圖:

階指的是,一個節點最多能有多少個子節點

image

首先,我需要插入一個關鍵字:30,可以得到如下的結果:

image

再插入26,得到如下的結果:

image

OK,此時如圖所示,在插入的那個終端結點中,它的關鍵字數已經超過了m-1=2,所以我們需要對結點進分裂,所以我們先對關鍵字排序,得到:26 30 37 ,所以它的左部分為(不包括中間值):26,中間值為:30,右部為:37,左部放在原來的結點,右部放入新的結點,而中間值則插入到父結點,並且父結點會產生一個新的指針,指向新的結點的位置,如下圖所示:

image

OK,然後我們繼續插入新的關鍵字:85,得到如下圖結果:

image

正如圖所示,我需要對剛纔插入的那個結點進行“分裂”操作,操作方式和之前的一樣,得到的結果如下:

image

哦,當我們分裂完後,突然發現之前的那個結點的父親結點的度為4了,說明它的關鍵字數超過了m-1,所以需要對其父結點進行“分裂”操作,得到如下的結果:

image


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • fdisk /dev/vdb mkfs.ext4 /dev/vdb echo '/dev/vdb /sdata ext4 defaults 0 0' >> /etc/fstab mount -a ...
  • ``` @echo off rem 提供Windows下nginx的啟動,重啟,關閉功能 echo begin cls ::ngxin 所在的盤符 set NGINX_PATH=E: ::nginx 所在目錄 set NGINX_DIR=E:\service\1\nginx-1.16.0\ colo... ...
  • 一、/etc/profile文件詳解(環境變數) 添加環境變數 ...
  • linux基本操作和常用命令(2) 第二部分主要是涉及到用戶和組的概念,以及一些操作。涉及到用戶和組的共三個文件,分別存放在/etc/shadow(密碼信息) /etc/group(組信息) /etc/passwd (用戶信息) 1:常用的命令有useradd,groupadd ,usermod,u ...
  • 1、概述 mysql為關係型資料庫。 mysql的分支-- mysql (自己本身) -- 2008前後的被SUN收購 SUN之後又被oracle收購 系統集成--什麼都乾(- 套解決方案) mariadb mysql被收購後,作者為了避免資料庫被壟斷,作者基於mysql的早期版本開發了mariad ...
  • 在運維工作中經常會遇到不知道密碼,密碼遺忘,密碼被他人修改過的情況,使用這種方式掃清你一切煩惱! 1、啟動Linux系統,在出現引導界面時,按“e”鍵,進入內核編輯界面;2、找到有“linux16”的這段參數,在此段末尾輸入“rd.break”;3、然後按“Ctrl+X”組合鍵進入緊急救援模式;4、 ...
  • `CDPATH`是shell的一個環境變數, 預設值為空: 將你常用的目錄添加到 的目錄列表中, 用':'冒號分隔, 比如, 當前目錄 ., home目錄 ~, 根目錄 /, 等等: 這樣就可以在任意位置cd到CDPATH列表中的目錄下了: 但是這樣設置只是臨時的, 在終端關閉後就失效了, 要想永久 ...
  • 環境: 1.VMware® Workstation 12 Pro 2.CentOS7 3.zookeeper-3.4.6 安裝步驟 1.下載zookeeper 本文使用的zookeeper下載地址如下(大家也可以下載其它版本) 鏈接:https://pan.baidu.com/s/1Ab9F53jN ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...