B树、B+树的java实现

一、B树的定义

在定义B树之前,首先明确一个概念,就是什么是树的阶?
树的阶指的是一个结点最多能有多少棵子树。例如:二叉树的阶就是2。

这个要跟结点的度区分开来,度是基于单个结点的,而阶是针对整棵树的。可以理解为树的阶是用来限制每个结点的度的。

B树,又称B-树,一棵m阶的B树,或为空树,或为满足下列特性的m叉树:
(1)树中每个结点至多有m棵子树。【解释:因为树的阶是m,所有这个是必然】
(2)若根结点不是叶子节点,则至少有两棵子树。
(3)除根结点之外的所有非叶子结点至少有⌈m/2⌉棵子树。【解释:第一条是用来限制所有节点度的最大值,2、3两条是用来限制根结点和非叶子结点度的最小值】
(4)所有的非叶子结点中包含下列信息数据
(n,P0,K0,P1,K1,P2,···,Kn-1,Pn)
其中,K[i] (i=0,···,n-1)为关键字,切K[i] < K[i+1](i=0,···,n-1),P[i] (i=0,1,···,n-1)为指向子树根结点的指针,且指针P[i]所指向的子树中的所有结点的关键字均小于K[i] (i=0,···,n-1),P[i+1]所指向的子树中的所有结点的关键字均大于K[i]。n为关键字的关键字的个数,且⌈m/2⌉-1 ≤ n ≤ m-1。【解释:指的关键字的左子树都比它小,右子树都比它大】
(5)所有叶子结点位于同一层

示例,3阶B树(m=3):
《B树、B+树的java实现》

二、B树的增删改查

1、B树的模型

package com.ghs.algorithm;

import java.util.List;

public class BTNode<K extends Comparable> {
    /** 关键字的个数 */

    private int number = 0;

    /** 关键字,0号单元未使用 */
    private List<K> keys;

    /** 子树 */
    private List<BTNode> children;

}
package com.ghs.algorithm;

public class BTree<K extends Comparable<K>>{

    /** 根节点 */
    private BTNode root;

    /** 阶 */
    private int order;
}

2、B树的查找操作

    /** * @title 查询key * @author ghs * @date 2017/11/10 21:53 * @param * @return */
    public Result getKey(K key){
        BTNode preNode = null;
        BTNode node = root;
        boolean found = false;
        int i = 0;
        while (node != null && !found){
            i = index(node, key);
            if(node.getKey(i).equals(key)){
                found = true;
            }else{
                preNode = node;
                node = node.getChildren(i);
            }
        }
        return new Result(found ? node:preNode, i, found);
    }

    /** * @title 查找key在node中的位置 * @author ghs * @date 2017/11/10 19:41 * @param * @return */
    private int index(BTNode<K> node, K key){
        //在keys[1...keyNum]中查找,使得keys[i]<= key < keys[i+1](0<i<keyNum-1)
        for (int i=0; i<node.getNumber(); i++){
            if (key.compareTo(node.getKey(i)) <= 0){
                return i;
            }
        }
        return node.getNumber();
    }

3、B树的插入

    public void addKey(K key){
        Result result = getKey(key);
        BTNode<K> node = result.getNode();
        int position = result.getPosition();
        K k = key;
        BTNode<K> rightNode = null;
        while (node!=null){
            add(node, position, k, rightNode);
            int number = node.getNumber();
            if(number < order){
                return;
            }else {
                int s = number%2==0 ? number/2 : number/2+1;
                split(node, s, rightNode);
                k = node.getKey(s);
                node = node.getParent();
                if (node != null) {
                    position = index(node, k);
                }
            }
        }
        newRoot(key);
    }

    private void split(BTNode<K> node, int s, BTNode<K> newNode){
        int number = node.getNumber();
        List<K> keys = node.getKeys();
        List<BTNode> children = node.getChildren();

        node.setKeys(keys.subList(0, s-1));
        node.setChildren(children.subList(0, s));
        node.setNumber(s-1);

        newNode.setKeys(keys.subList(s, number-1));
        newNode.setChildren(children.subList(s, number));
        newNode.setNumber(number-s);
    }
    private BTNode newRoot(K key){
        BTNode node = new BTNode();
        node.addKey(0, key);
        node.addChildren(0, nullBTNode);
        node.addChildren(1, nullBTNode);
        node.setNumber(1);
        return node;
    }
    原文作者:B树
    原文地址: https://blog.csdn.net/u011983531/article/details/78377026
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞