B-树,也称为B树(Banlance Tree),是一种平衡的多叉树。

定义

  1. B树的叶子节点都需要在同一层
  2. 假设B树的度为t,该值取决于磁盘的块大小
  3. 除了根节点,每个节点至少包含t-1个键,根节点至少包含1个键
  4. 所有节点最多包含2*t-1个键
  5. 每个节点的子节点个数为其键的个数+1
  6. 所有的节点必须是升序,k1和k2的子节点,就包含了从k1到k2全部的值(range搜索)
  7. 插入只会发生在叶子节点

    操作

    Traversal

    类似于二叉树的中序遍历

    Search

    算法

  8. 搜索k

  9. 从根节点出发
  10. 对于非叶子节点,如果节点中存在k,则返回该非叶子节点
  11. 否则选择第一个比k大的叶子节点
  12. 当到达叶子节点,叶子节点中没有k,则返回null

    示例

    搜索120
    image.png
    image.png
    image.png
    image.png

    代码

    ```java // Java program to illustrate the sum of two numbers

// A BTree class Btree { public BTreeNode root; // Pointer to root node public int t; // Minimum degree

  1. // Constructor (Initializes tree as empty)
  2. Btree(int t) {
  3. this.root = null;
  4. this.t = t;
  5. }
  6. // function to traverse the tree
  7. public void traverse() {
  8. if (this.root != null)
  9. this.root.traverse();
  10. System.out.println();
  11. }
  12. // function to search a key in this tree
  13. public BTreeNode search(int k) {
  14. if (this.root == null)
  15. return null;
  16. else
  17. return this.root.search(k);
  18. }

}

// A BTree node class BTreeNode { int[] keys; // An array of keys int t; // Minimum degree (defines the range for number of keys) BTreeNode[] C; // An array of child pointers int n; // Current number of keys boolean leaf; // Is true when node is leaf. Otherwise false

// Constructor
BTreeNode(int t, boolean leaf) {
    this.t = t;
    this.leaf = leaf;
    this.keys = new int[2 * t - 1];
    this.C = new BTreeNode[2 * t];
    this.n = 0;
}

// A function to traverse all nodes in a subtree rooted with this node
public void traverse() {

    // There are n keys and n+1 children, traverse through n keys
    // and first n children
    int i = 0;
    for (i = 0; i < this.n; i++) {

        // If this is not leaf, then before printing key[i],
        // traverse the subtree rooted with child C[i].
        if (this.leaf == false) {
            C[i].traverse();
        }
        System.out.print(keys[i] + " ");
    }

    // Print the subtree rooted with last child
    if (leaf == false)
        C[i].traverse();
}

// A function to search a key in the subtree rooted with this node.
BTreeNode search(int k) { // returns NULL if k is not present.

    // Find the first key greater than or equal to k
    int i = 0;
    while (i < n && k > keys[i])
        i++;

    // If the found key is equal to k, return this node
    if (keys[i] == k)
        return this;

    // If the key is not found here and this is a leaf node
    if (leaf == true)
        return null;

    // Go to the appropriate child
    return C[i].search(k);

}

} ```

Insert

算法

谨记插入只能发生在叶子节点,不能发生在非叶子节点。

设度为t

  1. 使用搜索算法找到合适的叶子节点
  2. 尝试插入到该叶子节点
  3. 如果该叶子节点的key个数小于t,则插入
  4. 如果该叶子节点已经达到t,则分裂成两个,左侧为前t/2个,中间为中数,右侧为后t/2个
  5. 将中数上移到父节点
  6. 如果父节点同样达到t个,则重复分裂
  7. 插入节点

    示例

    空节点插入10,20,30,40,50,60,70,80,90,度为5

  8. 插入10、20、30、40

    image.png

  9. 插入50

    image.png

    1. 该叶子节点key值个数已经为5
    2. 分裂
    3. 左侧为10、20,右侧为40、50,中数30上移
  10. 插入60、70

    image.png

  1. 插入70、80

    image.png

  2. 插入90

    image.png

    1. 从根节点出发
    2. x不是叶子节点
    3. 90>30,y=右侧节点
    4. y是满节点,将其分割成两个节点,中数向上层移动
    5. 90>60,则x指向右侧70,插入90

Delete