日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務,提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

B-Tree定義

在計算機科學中,B樹(英語:B-tree)是一種自平衡的樹,能夠保持數(shù)據(jù)有序。這種數(shù)據(jù)結構能夠讓查找數(shù)據(jù)、順序訪問、插入數(shù)據(jù)及刪除的動作,都在對數(shù)時間內(nèi)完成。

B-Tree的特點

1、樹中每個結點最多含有m個孩子(m>=2);

2、除根結點和葉子結點外,其它每個結點至少有[ceil(m / 2)]個孩子(其中ceil(x)是一個取上限的函數(shù));

3、若根結點不是葉子結點,則至少有2個孩子(特殊情況:沒有孩子的根結點,即根結點為葉子結點,整棵樹只有一個根節(jié)點);

4、所有葉子結點都出現(xiàn)在同一層(最底層),葉子結點為外部結點,保存內(nèi)容,即key和value。

5、其他結點為內(nèi)部結點,保存索引,即key和next。

B-Tree 數(shù)據(jù)結構詳解及Java代碼實現(xiàn)

 

每個節(jié)點占用一個盤塊的磁盤空間,一個節(jié)點上有兩個升序排序的關鍵字和三個指向子樹根節(jié)點的指針,指針存儲的是子節(jié)點所在磁盤塊的地址。兩個關鍵詞劃分成的三個范圍域?qū)齻€指針指向的子樹的數(shù)據(jù)的范圍域。以根節(jié)點為例,關鍵字為17和35,P1指針指向的子樹的數(shù)據(jù)范圍為小于17,P2指針指向的子樹的數(shù)據(jù)范圍為17~35,P3指針指向的子樹的數(shù)據(jù)范圍為大于35。

模擬查找關鍵字29的過程:

1、根據(jù)根節(jié)點找到磁盤塊1,讀入內(nèi)存。【磁盤I/O操作第1次】

2、比較關鍵字29在區(qū)間(17,35),找到磁盤塊1的指針P2。

3、根據(jù)P2指針找到磁盤塊3,讀入內(nèi)存。【磁盤I/O操作第2次】

4、比較關鍵字29在區(qū)間(26,30),找到磁盤塊3的指針P2。

5、根據(jù)P2指針找到磁盤塊8,讀入內(nèi)存。【磁盤I/O操作第3次】

6、在磁盤塊8中的關鍵字列表中找到關鍵字29。

分析上面過程,發(fā)現(xiàn)需要3次磁盤I/O操作,和3次內(nèi)存查找操作。由于內(nèi)存中的關鍵字是一個有序表結構,可以利用二分法查找提高效率。而3次磁盤I/O操作是影響整個B-Tree查找效率的決定因素。B-Tree相對于AVLTree縮減了節(jié)點個數(shù),使每次磁盤I/O取到內(nèi)存的數(shù)據(jù)都發(fā)揮了作用,從而提高了查詢效率。

JAVA代碼實現(xiàn)


package tree;
 
 
/**
 * Created by bruce_shan on 2018/7/8 17:08.
 * Description : B-樹 也作 B樹 java 實現(xiàn)
 */
public class BTree<Key extends Comparable<Key>, Value> {
 
 private static final int M = 4; // B樹的階數(shù)
 
 private Node root; // B-tree 的根節(jié)點
 private int height; // B-tree 的高度
 private int N; // B-tree 樹中鍵值對的數(shù)目
 
 // B-tree 節(jié)點類型
 private static final class Node {
 private int m; // number of children
 private Entry[] children = new Entry[M]; // the array of children
 // create a node with k children
 private Node(int k) {
 m = k;
 }
 }
 // B-tree 節(jié)點中的元素類型
 private static class Entry {
 private Comparable key;
 private Object val;
 private Node next; // 指向節(jié)點中下一元素
 public Entry(Comparable key, Object val, Node next) {
 this.key = key;
 this.val = val;
 this.next = next;
 }
 }
 
 
 /**
 * 初始化空 B-tree樹
 */
 public BTree() {
 root = new Node(0);
 }
 
 /**
 * 判斷 B-tree 是否是空樹
 */
 public boolean isEmpty() {
 return size() == 0;
 }
 
 public int size() {
 return N;
 }
 
 public int height() {
 return height;
 }
 
 /**
 * get操作
 */
 public Value get(Key key) {
 if (key == null) throw new NullPointerException("key must not be null");
 return search(root, key, height);
 }
 
 /**
 * put 操作
 */
 public void put(Key key, Value val) {
 if (key == null) throw new NullPointerException("key must not be null");
 Node u = insert(root, key, val, height);
 N++;
 if (u == null) return;
 
 // need to split root
 Node t = new Node(2);
 t.children[0] = new Entry(root.children[0].key, null, root);
 t.children[1] = new Entry(u.children[0].key, null, u);
 root = t;
 height++;
 }
 
 
 // 搜索操作
 private Value search(Node x, Key key, int ht) {
 Entry[] children = x.children;
 
 // 節(jié)點內(nèi)數(shù)組操作 內(nèi)部遍歷
 if (ht == 0) {
 for (int j = 0; j < x.m; j++) {
 if (equals(key, children[j].key)) return (Value) children[j].val;
 }
 }
 
 // 外部定位
 else {
 for (int j = 0; j < x.m; j++) {
 if (j+1 == x.m || less(key, children[j+1].key))
 return search(children[j].next, key, ht-1);
 }
 }
 return null;
 }
 // 插入操作
 private Node insert(Node h, Key key, Value val, int ht) {
 int j;
 Entry t = new Entry(key, val, null);
 
 // 節(jié)點內(nèi)部數(shù)組操作
 if (ht == 0) {
 for (j = 0; j < h.m; j++) {
 if (less(key, h.children[j].key)) break;
 }
 }
 // 外部遍歷
 else {
 for (j = 0; j < h.m; j++) {
 if ((j+1 == h.m) || less(key, h.children[j+1].key)) {
 Node u = insert(h.children[j++].next, key, val, ht-1);
 if (u == null) return null;
 t.key = u.children[0].key;
 t.next = u;
 break;
 }
 }
 }
 
 for (int i = h.m; i > j; i--)
 h.children[i] = h.children[i-1];
 h.children[j] = t;
 h.m++;
 if (h.m < M) return null;
 else return split(h);
 }
 
 // 分裂節(jié)點成兩半
 private Node split(Node h) {
 Node t = new Node(M/2);
 h.m = M/2;
 for (int j = 0; j < M/2; j++)
 t.children[j] = h.children[M/2+j];
 return t;
 }
 // 判斷兩個元素是否相等
 private boolean equals(Comparable k1, Comparable k2) {
 return k1.compareTo(k2) == 0;
 }
 
 // 判斷兩個元素的大小
 private boolean less(Comparable k1, Comparable k2) {
 return k1.compareTo(k2) < 0;
 }
}



引入B-Tree的原因

首先,包括紅黑樹是將輸入存入內(nèi)存的一種內(nèi)部查找樹。而B樹是前面平衡樹算法的擴展,它支持保存在磁盤或者網(wǎng)絡上的符號表進行外部查找,這些文件可能比我們以前考慮的輸入要大的多(難以存入內(nèi)存)。

既然內(nèi)容保存在磁盤中,那么自然會因為樹的深度過大而造成磁盤I/O讀寫過于頻繁(磁盤讀寫速率是有限制的),進而導致查詢效率低下。

那么降低樹的深度自然很重要了。因此,我們引入了B樹,平衡多路查找樹。

分享到:
標簽:數(shù)據(jù)結構
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定