多路查詢樹開篇

2021-07-07 07:37:55 字數 2479 閱讀 2579

前言(自己加的)

動態查詢樹主要有:二叉查詢樹(binary search tree),平衡二叉查詢樹

(balanced binary search tree),紅黑樹(red-black tree ),b-tree/b+-tree/ b*-tree (b~tree)。前三者是典型的二叉查詢樹結構,其查詢的時間複雜度o(log2n)與樹的深度相關,那麼降低樹的深度自然會提高查詢效率。 

但是咱們有面對這樣乙個實際問題:就是大規模資料儲存中,實現索引查詢這樣一

個實際背景下,樹節點儲存的元素數量是有限的(如果元素數量非常多的話,查詢就退化成節點內部的線性查詢了),這樣導致二叉查詢樹結構由於樹的深度過大而造成磁碟i/o讀寫過於頻繁,進而導致查詢效率低下(為什麼會出現這種情況,待會在外部儲存器-磁碟中有所解釋),那麼如何減少樹的深度(當然是不能減少查詢的資料量),乙個基本的想法就是:採用多叉樹結構(由於樹節點元素數量是有限的,自然該節點的子樹數量也就是有限的)。 

這樣我們就提出了乙個新的查詢樹結構——多路查詢樹。根據平衡二叉樹的啟發,

自然就想到平衡多路查詢樹結構,也就是這篇文章所要闡述的第乙個主題b~tree(b樹結構)。

有一點,再次強調下:b-樹,即為b樹。因為b樹的原英文名稱為b-tree,而國內很多人喜歡把b-tree譯作b-樹,其實,這是個非常不好的直譯,很容易讓人產生誤解。如人們可能會以為b-樹是一種樹,而b樹又是一種樹。而事實上是,b-tree就是指的b樹

1、引言

以前我們所討論的資料結構,處理資料都是在記憶體中。假如我們所要操作的資料集非常大,大到記憶體無法處理了怎麼辦?如資料庫上千萬記錄的資料表、硬碟中上萬個檔案等。在這種情況下,對資料的處理需要不斷的從硬碟等儲存裝置中調入或者調出記憶體頁面。而過多的進行io讀寫,顯然會降低系統的效率。為了降低對外存的訪問次數,我們就需要新的資料結構來處理這樣的問題。

2、2-3樹

每個節點都具有2個孩子(稱之為2節點)或者3個孩子(稱之為3節點)。

乙個2節點包含乙個元素和兩個孩子(或沒有孩子)。

乙個3節點包含兩個元素和三個孩子(或沒有孩子)。

3、2-3-4樹

每個節點都具有2個孩子(稱之為2節點)或者3個孩子(稱之為3節點)或者4個孩子(稱之為4節點)。

乙個2節點包含乙個元素和兩個孩子(或沒有孩子)。

乙個3節點包含兩個元素和三個孩子(或沒有孩子)。

乙個4節點包含三個元素和四個孩子(或沒有孩子)。

4、b樹

b樹是一種多路查詢樹,2-3樹和2-3-4樹都是b樹的特例。節點最大的孩子數目稱為b樹的階,因此2-3樹是3階b樹,2-3-4樹是4階b樹 。

乙個m階的b樹具有如下性質:

1)如果根節點不是葉子節點,則其子樹個數範圍為[2,m];

2)分支節點子樹範個數圍為[m/2,m];

3)所有葉子節點在同一層次;

4)所有分支節點包含下列資訊:關鍵字個數n,關鍵字k1,...,kn,指向子樹根結點的指標a0,...,an。

如果記憶體與外存交換資料次數頻繁,會造成時間上的瓶頸,那麼b樹結構是怎麼做到減少次數呢?

我們的外存,比如硬碟,是將所有資訊分割成相等大小的頁面,每次硬碟讀寫的都是乙個或多個完整的頁面。在乙個典型的b樹應用中,要處理的硬碟資料量很大,因此無法一次全部裝入記憶體。因此我們會對b樹進行調整,使得b樹的階數(或節點的元素)與硬碟儲存的面頁面大小相匹配。比如說一顆b樹的階為1001(即乙個節點包含1000個關鍵字),高度為2,他可以儲存超過10億個關鍵字,我們只要讓根節點持久的保留在記憶體中,那麼在這棵樹上,尋找某乙個關鍵字至多需要兩次硬碟的讀取。通過這種方式,在有限記憶體的情況下,每一次磁碟的訪問我們都可以獲得最大量的資料。由於b樹每個節點可以具有比二叉樹多得多的元素,所以與二叉樹相比,它們減少了必須訪問節點和資料塊的數量,從而提高了效能。可以說b樹的資料結構就是為內外存的資料互動準備的。

5、b+樹

對於樹結構來說,我們都可以通過中序遍歷來順序查詢樹中的元素,這一切都是在記憶體中進行。可是b樹結構中,我們往返於每個節點之間也就意味著,我們必須在硬碟的頁面之間進行多次訪問。

為了能夠解決所有元素遍歷等基本問題,我們在原有b樹結構基礎上,加上了新的元素組織方式,這就是b+樹。

b+樹不同與b-樹的地方:

1)有n棵子樹的節點中包含n個關鍵字

2)所有的葉子節點包含全部關鍵資訊,及指向含這些關鍵字記錄的指標

3)所有分支結點可以看成是索引,節點中僅含有其子樹中的最大(或最小)關鍵字

這樣的資料結構最大的好處就是,如果是要隨機查詢,我們就從根節點出發,與b樹的查詢方式相同,只不過即使在分支節點找到了待查詢的關鍵字,它也直是用來索引的,不能提供實際記錄的訪問,還是需要到達包含此關鍵字的終端節點。

如果我們是要從最小關鍵字從小到大進行順序查詢,我們就可以從最左側的葉子節點出發,不經過分支節點,而是沿著指向下乙個葉子節點的指標遍歷所有的關鍵字。

多路查詢樹

二叉樹的操作效率較高,但是也存在問題,請看下面的二叉樹 二叉樹需要載入到記憶體的,如果二叉樹的節點少,沒有什麼問題,但是如果二叉樹的節點很多 比如1億 就 存在如下問題 問題1 在構建二叉樹時,需要多次進行i o操作 海量資料存在資料庫或檔案中 節點海量,構建二叉樹時,速度有影響 問題2 節點海量,...

多路查詢樹

二叉樹的操作效率較高,但也存在問題 二叉樹需要載入到記憶體,如果二叉樹的節點少,沒有什麼問題,但是如果二叉樹的節點很多 比如1億 就存在如下問題 問題1 在構建二叉樹時,需要多次進行io操作 海量資料存在資料庫或檔案中 節點海量,構建二叉樹時,速度有影響 問題2 節點海量,也會造成二叉樹的高度很大,...

多路查詢樹

二叉樹的操作效率較高,但是也存在問題 二叉樹需要載入到記憶體的,如果二叉樹的節點少,沒有什麼問題,但是如果二叉樹的節點很多 比如1億 就存在如下問題 問題1 在構建二叉樹時,需要多次進行i o操作 海量資料存在資料庫或檔案中 節點海量,構建二叉樹時,速度有影響 問題2 節點海量,也會造成二叉樹的高度...