B树、B+树的java实现

来源:互联网 发布:手机怎样举报淘宝卖家 编辑:程序博客网 时间:2024/06/13 23:36

一、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树的增删改查

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;    }
原创粉丝点击