title: 資料結構之b+樹
date: 2018-11-04 20:39:00
tags: 資料結構與演算法之美
一、 **b-樹索引
1.b-樹的特性
一棵m階b-樹,或者是空樹,或者是滿足以下性質的m叉樹
根結點至少有兩個分支;
除根以外的非葉結點,每個結點包含分支數範圍[[m/2],m],即關鍵字字數的範圍是[[m/2]-1,m-1],其中[m/2]表示取大於等於m/2的最小整數
所有葉子結點都在樹的同一層上,並且指標域為空;
所有的非終端結點應包含如下資訊: (n,a0,k1,a1,k2,a2,… ,kn,an),結點內關鍵字互不相等,且從小到大排列。
解釋:m階的意思是這顆樹最多的分支是多少,每個節點可以包含很多關鍵字,範圍是[[m/2]-1,m-1],比如m為 3,就說明是3階的b-樹,
那麼它的樹的節點的關鍵字最少2,最多4個。下面的b+樹也是同樣的理解。
2.b-樹索引結構圖
3.b-樹查詢代價分析
設關鍵字的總數為 n ,求 m階 b- 樹的最大層次 l。
二、 b+樹的索引結構
1.b+樹特性
在實際的檔案系統中,基本上不使用b_樹,而是使用b_樹的一種變體,稱為m階b+樹。 它與b-樹的主要不同是葉子結點中儲存記錄。在b+樹中,所有的非葉子結點可以看成是索引,而其中的關鍵字是作為「分界關鍵
字」,用來界定某一關鍵字的記錄所在的子樹。一棵m階b+樹與m階b-樹的主要差異是:
1.若乙個結點有n棵子樹,則必含有n個關鍵字;
2.所有葉子結點中包含了全部記錄的關鍵字資訊以及這些關鍵字記錄的指標,而且葉子結點按關鍵字的大小從小到大順序鏈結;
3.所有的非葉子結點可以看成是索引的部分,結點中只含有其子樹的根結點中的最大(或最小)關鍵字。
2.b+樹索引結構圖
三、 b+樹的索引操作
1.b+樹查詢
對b+樹可以進行兩種查詢運算:
從最小關鍵字開始,進行順序查詢。
從根結點開始,進行隨機查詢
在查詢時,若非終端結點上的關鍵值等於給定值,並不終止,而是繼續向下直到葉子結點。因此,在b+樹中,不管查詢成功與否,每次查詢都是走了一條從根到葉子結點的路徑。其餘同b-樹的查詢類似。
// 在樹中查詢資料
bool bplustree::search(key_type data, char* spath)
int i = 0;
int offset = 0;
if (null != spath)
(void)sprintf(spath+offset, "the serach path is:");
offset+=19;
cnode * pnode = getroot();
// 迴圈查詢對應的葉子結點
while (null != pnode)
// 結點為葉子結點,迴圈結束
if (node_type_leaf == pnode->gettype())
break;
// 找到第乙個鍵值大於等於key的位置
for (i = 1; (data >= pnode->getelement(i) )&& (i <= pnode->getcount()); i++)
if (null != spath)
(void)sprintf(spath+offset, " %3d -->", pnode->getelement(1));
offset+=8;
pnode = pnode->getpointer(i);
// 沒找到
if (null == pnode)
return false;
if (null != spath)
(void)sprintf(spath+offset, "%3d", pnode->getelement(1));
offset+=3;
// 在葉子結點中繼續找
bool found = false;
for (i = 1; (i <= pnode->getcount()); i++)
if (data == pnode->getelement(i))
found = true;
if (null != spath)
if (true == found)
(void)sprintf(spath+offset, " ,successed.");
else
(void)sprintf(spath+offset, " ,failed.");
return found;
2.b+樹查詢代價分析
3.b+樹插入
m階b樹的插入操作在葉子結點上進行,假設要插入關鍵值a,找到葉子結點後插入a,做如下演算法判別:
1、如果當前結點是根結點並且插入後結點關鍵字數目小於等於m,則演算法結束;
2、如果當前結點是非根結點並且插入後結點關鍵字數目小於等於m,則判斷若a是新索引值時轉步驟④後結束,若a不是新索引值則直接結束;
3、如果插入後關鍵字數目大於m(階數),則結點先**成兩個結點x和y,並且他們各自所含的 關鍵字個數分別為:u=大於(m+1)/2的最小整數,v=小於(m+1)/2的最大整數;由於索引值位於結點的最左端或者最右端,不妨假設索引值位於結點最右端,有如下操作:
a)如果當前**成的x和y結點原來所屬的結點是根結點,則從x和y中取出索引的關鍵字,將這兩個關鍵字組成新的根結點,並且這個根結點指向x和y,演算法結束;
b)如果當前**成的x和y結點原來所屬的結點是非根結點,依據假設條件判斷,如果a成為y的新索引值,則轉步驟④得到y的雙親結點p,如果a不是y結點的新索引值,則求出x和y結點的雙親結點p;然後提取x結點中的新索引值a』,在p中插入關鍵字a』,從p開始,繼續進行插入演算法;
4.b+樹的插入過程
5.b+樹的刪除操作
b+樹的刪除僅在葉結點上進行。
當葉子結點中的最大關鍵字被刪除時,其在非終端結點中的值可以作為乙個「分界關鍵字」存在。若因刪除而使結點中關鍵字的個數少於m/2 (m/2結果取上界,如5/2結果為3)時,其和兄弟結點的合併過程亦和b-樹類似。
6.b+樹的刪除過程
四、 b+樹的優分析
1.為什麼選擇b+樹?
1、b+樹的磁碟讀寫代價更低
我們都知道磁碟時可以塊儲存的,也就是同乙個磁軌上同一盤塊中的所有資料都可以一次全部讀取。而b+樹的內部結點並沒有指向關鍵字具體資訊的指標 。因此其內部結點相對b_樹更小。如果把所有同一內部結點的關鍵字存放在同一盤塊中,那麼盤塊所能容納的關鍵字數量也越多。這樣,一次性讀入記憶體中的需要查詢的關鍵字也就越多。相對來說io讀寫次數也就降低了。
2、b+樹的查詢效率更加穩定。
由於非終結點並不是最終指向檔案內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查詢必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每乙個資料的查詢效率相當。
資料視覺化 什麼是資料視覺化
資料對應的英文單詞是data,從資訊獲取的角度看,資料是對目標觀察和記錄的結果,是現實世界中的時間 地點 事件 其他物件或概念的描述。不同學者對資料的作用也給出不同的定義,大致分為以下3類 視覺化對應的兩個英文單詞 visualize和visualization。visualize是動詞,描述 生成...
資料視覺化
資料視覺化主要旨在借助於圖形化手段,清晰有效地傳達與溝通資訊。但是,這並不就意味著資料視覺化就一定因為要實現其功能用途而令人感到枯燥乏味,或者是為了看上去絢麗多彩而顯得極端複雜。為了有效地傳達思想概念,美學形式與功能需要齊頭並進,通過直觀地傳達關鍵的方面與特徵,從而實現對於相當稀疏而又複雜的 資料集...
資料視覺化
畫餅圖 def print pie input data res for each in input data res each res.get each,0 1 label x for j in res fig plt.figure plt.pie x,labels label,autopct 1...