, V> { // 是否为叶子节点 protected boolean isLeaf; //是否是根节点 protected boolean isRoot; // 父节点 pr_java b+数据落盘">
赞
踩
BPlusNode.java
- package BplusTree;
-
- import java.util.*;
-
- @SuppressWarnings("all")
- public class BPlusNode<K extends Comparable<K>, V> {
-
- // 是否为叶子节点
- protected boolean isLeaf;
-
- //是否是根节点
- protected boolean isRoot;
-
- // 父节点
- protected BPlusNode<K, V> parent;
-
- // 叶节点的前驱节点
- protected BPlusNode<K, V> previous;
-
- // 叶节点的后继节点
- protected BPlusNode<K, V> next;
-
- // 节点的关键字列表
- protected List<Map.Entry<K, V>> entries;
-
- // 子节点列表
- protected List<BPlusNode<K, V>> children;
-
- //构造方法
- public BPlusNode(boolean isLeaf) {
- this.isLeaf = isLeaf;
- entries = new ArrayList();
- //如果不是叶子结点,则有孩子列表
- if (!isLeaf) {
- children = new ArrayList();
- }
- }
-
- //构造方法
- public BPlusNode(boolean isLeaf, boolean isRoot) {
- this(isLeaf);
- this.isRoot = isRoot;
- }
-
- //单值查找,找到key对应的value值
- public V query(K key) {
- //如果是叶子节点
- if (isLeaf) {
- //二分查找
- int low = 0, high = entries.size() - 1, mid;
- int comp;
- while (low <= high) {
- mid = (low + high) / 2;
- comp = entries.get(mid).getKey().compareTo(key);
- //等于key值
- if (comp == 0) {
- //在entries列表中取value值
- return entries.get(mid).getValue();
- } else if (comp < 0) {
- low = mid + 1;
- } else {
- high = mid - 1;
- }
- }
- //未找到所要查询的对象
- return null;
- }
-
- //如果不是叶子节点
- //如果key小于节点最左边的key,沿第一个子节点继续递归地搜索
- if (key.compareTo(entries.get(0).getKey()) < 0) {
- return children.get(0).query(key);
- //如果key大于等于节点最右边的key,沿最后一个子节点继续递归地搜索
- } else if (key.compareTo(entries.get(entries.size() - 1).getKey()) >= 0) {
- return children.get(children.size() - 1).query(key);
- //否则沿比key大的前一个子节点继续递归地搜索
- } else {
- //二分查找
- int low = 0, high = entries.size() - 1, mid = 0;
- int comp;
- while (low <= high) {
- mid = (low + high) / 2;
- comp = entries.get(mid).getKey().compareTo(key);
- if (comp == 0) {
- return children.get(mid + 1).query(key);
- } else if (comp < 0) {
- low = mid + 1;
- } else {
- high = mid - 1;
- }
- }
- return children.get(low).query(key);
- }
- }
-
- //范围查找
- public List<Map.Entry<K, V>> rangeQuery(K startInclude ,K endExclude){
- //如果是叶子结点
- if(isLeaf) {
- //result存放结果
- List<Map.Entry<K, V>> result = new ArrayList<>();
- int start =findIndex(startInclude);
- int end=findIndex(endExclude);
- for(int i=start;i<end;i++) {
- result.addAll((Collection<? extends Map.Entry<K, V>>) entries.get(i));
- }
- BPlusNode<K,V> nextLeaf = this.next;
- while(nextLeaf!=null){
- for(int i=0;i<nextLeaf.entries.size();++i){
- if(nextLeaf.entries.get(i).getKey().compareTo(endExclude)<0){
- result.addAll((Collection<? extends Map.Entry<K, V>>) nextLeaf.entries.get(i));
- }
- else{
- return result;
- }
- }
- }
- }
-
- //如果不是叶子节点
- //如果下界仍小于最左边的key,沿第一个子节点继续递归地搜索
- if (startInclude.compareTo(entries.get(0).getKey()) < 0) {
- return children.get(0).rangeQuery(startInclude,endExclude);
- //如果上界还大于等于节点最右边的key,沿最后一个子节点继续递归地搜索
- } else if (endExclude.compareTo(entries.get(entries.size() - 1).getKey()) >= 0) {
- return children.get(children.size() - 1).rangeQuery(startInclude,endExclude);
- //否则沿比下界大的前一个子节点继续递归地搜索
- } else {
- //二分查找
- int low = 0, high = entries.size() - 1, mid = 0;
- int comp;
- while (low <= high) {
- mid = (low + high) / 2;
- comp = entries.get(mid).getKey().compareTo(startInclude);
- if (comp == 0) {
- return children.get(mid + 1).rangeQuery(startInclude,endExclude);
- } else if (comp < 0) {
- low = mid + 1;
- } else {
- high = mid - 1;
- }
- }
- return children.get(low).rangeQuery(startInclude,endExclude);
- }
- }
-
- //二分查找找到key在entries中的位置
- protected int findIndex(K key) {
- int l = 0;
- int r = entries.size() - 1;
- int index = entries.size();
- while (l <= r) {
- int mid = l + ((r - l) >> 1);
- if (entries.get(mid).getKey().compareTo(key) >= 0) {
- index = mid;
- r = mid - 1;
- } else {
- l = mid + 1;
- }
- }
- return index;
- }
-
- //插入 将key value键值对插入tree
- public void insertOrUpdate(K key, V value, BPlusTree<K, V> tree) {
- //如果是叶子节点
- if (isLeaf) {
- //小于树的度,不需要分裂,直接插入或更新
- if (contains(key) != -1 || entries.size() < tree.getOrder()) {
- insertOrUpdate(key, value);
- if (tree.getHeight() == 0) {
- tree.setHeight(1);
- }
- return;
- }
- //需要分裂
- //分裂成左右两个节点
- BPlusNode<K, V> left = new BPlusNode<K, V>(true);
- BPlusNode<K, V> right = new BPlusNode<K, V>(true);
- //设置链接
- if (previous != null) {
- //前驱结点的next指针指向left
- previous.next = left;
- left.previous = previous;
- }
- if (next != null) {
- //后继结点的pre指针指向right
- next.previous = right;
- right.next = next;
- }
- //没有前驱
- if (previous == null) {
- tree.setHead(left);
- }
- //left的后继指针指向right
- left.next = right;
- //right的前驱指针指向left
- right.previous = left;
- //pre和next置空
- previous = null;
- next = null;
-
- //把原节点关键字复制到到分裂出来的两个新节点
- copy2Nodes(key, value, left, right, tree);
-
- //如果不是根节点
- if (parent != null) {
- //调整父子节点关系
- //在父节点的children序列中的位置
- int index = parent.children.indexOf(this);
- //移除当前结点
- parent.children.remove(this);
- //更新左右新结点的parent
- left.parent = parent;
- right.parent = parent;
- //在父节点的children序列中添加两个新结点
- parent.children.add(index, left);
- parent.children.add(index + 1, right);
- //在父节点的关键字列表的index位置中添加右结点的第一个关键字
- parent.entries.add(index, right.entries.get(0));
- entries = null; //删除当前节点的关键字信息
- children = null; //删除当前节点的孩子节点引用
-
- //父节点插入或更新关键字
- parent.updateInsert(tree);
- parent = null; //删除当前节点的父节点引用
-
- //如果是根节点
- } else {
- isRoot = false;
- //新建根节点
- BPlusNode<K, V> parent = new BPlusNode<K, V>(false, true);
- tree.setRoot(parent);
- //把相应的指针和序列更新
- left.parent = parent;
- right.parent = parent;
- parent.children.add(left);
- parent.children.add(right);
- parent.entries.add(right.entries.get(0));
- entries = null;
- children = null;
- }
- return;
-
- }
- //如果不是叶子节点
- //如果key小于等于节点最左边的key,沿第一个子节点继续递归地搜索
- if (key.compareTo(entries.get(0).getKey()) < 0) {
- children.get(0).insertOrUpdate(key, value, tree);
- //如果key大于节点最右边的key,沿最后一个子节点继续递归地搜索
- } else if (key.compareTo(entries.get(entries.size() - 1).getKey()) >= 0) {
- children.get(children.size() - 1).insertOrUpdate(key, value, tree);
- //否则沿比key大的前一个子节点继续递归地搜索
- } else {
- //二分查找
- int low = 0, high = entries.size() - 1, mid = 0;
- int comp;
- while (low <= high) {
- mid = (low + high) / 2;
- comp = entries.get(mid).getKey().compareTo(key);
- if (comp == 0) {
- children.get(mid + 1).insertOrUpdate(key, value, tree);
- break;
- } else if (comp < 0) {
- low = mid + 1;
- } else {
- high = mid - 1;
- }
- }
- if (low > high) {
- children.get(low).insertOrUpdate(key, value, tree);
- }
- }
- }
-
- //把原节点关键字复制到到分裂出来的两个新节点
- private void copy2Nodes(K key, V value, BPlusNode<K, V> left,
- BPlusNode<K, V> right, BPlusTree<K, V> tree) {
- //左右两个节点关键字长度,比方说原结点有5个数,则left分2个,right分3个
- int leftSize = (tree.getOrder() + 1) / 2 + (tree.getOrder() + 1) % 2;
- boolean b = false;//用于记录新元素是否已经被插入
- for (int i = 0; i < entries.size(); i++) {
- //左结点
- if (leftSize != 0) {
- leftSize--;
- if (!b && entries.get(i).getKey().compareTo(key) > 0) {
- //在左节点的entries序列中新建一个存放新元素
- left.entries.add(new AbstractMap.SimpleEntry<K, V>(key, value));
- b = true;
- i--;
- } else {
- left.entries.add(entries.get(i));
- }
- //右结点
- } else {
- if (!b && entries.get(i).getKey().compareTo(key) > 0) {
- //在右节点的entries序列中新建一个存放新元素
- right.entries.add(new AbstractMap.SimpleEntry<K, V>(key, value));
- b = true;
- i--;
- } else {
- right.entries.add(entries.get(i));
- }
- }
- }
- //新元素仍没插入,说明新元素最大,把它放在右节点
- if (!b) {
- right.entries.add(new AbstractMap.SimpleEntry<K, V>(key, value));
- }
- }
-
- /**
- * 插入节点后中间节点的更新
- */
- protected void updateInsert(BPlusTree<K, V> tree) {
-
- //如果子节点数超出阶数,则需要分裂该节点
- if (children.size() > tree.getOrder()) {
- //分裂成左右两个节点
- BPlusNode<K, V> left = new BPlusNode<K, V>(false);
- BPlusNode<K, V> right = new BPlusNode<K, V>(false);
- //左右两个节点子节点的长度
- int leftSize = (tree.getOrder() + 1) / 2 + (tree.getOrder() + 1) % 2;
- int rightSize = (tree.getOrder() + 1) / 2;
- //复制子节点到分裂出来的新节点,并更新关键字
- for (int i = 0; i < leftSize; i++) {
- left.children.add(children.get(i));
- //把每个孩子的parent指针指向left
- children.get(i).parent = left;
- }
- for (int i = 0; i < rightSize; i++) {
- right.children.add(children.get(leftSize + i));
- //把每个孩子的parent指针指向right
- children.get(leftSize + i).parent = right;
- }
- for (int i = 0; i < leftSize - 1; i++) {
- //更新左节点的entries列表
- left.entries.add(entries.get(i));
- }
- for (int i = 0; i < rightSize - 1; i++) {
- //更新右节点的entries列表
- right.entries.add(entries.get(leftSize + i));
- }
-
- //如果不是根节点
- if (parent != null) {
- //调整父子节点关系
- int index = parent.children.indexOf(this);
- //在父节点的children列表中移除当前结点
- parent.children.remove(this);
- //更新指针指向
- left.parent = parent;
- right.parent = parent;
- //更新列表
- parent.children.add(index, left);
- parent.children.add(index + 1, right);
- parent.entries.add(index, entries.get(leftSize - 1));
- //原来的置空
- entries = null;
- children = null;
-
- //递归调用 父节点更新关键字
- parent.updateInsert(tree);
- parent = null;
- //如果是根节点
- } else {
- isRoot = false;
- //新建根节点
- BPlusNode<K, V> parent = new BPlusNode<K, V>(false, true);
- tree.setRoot(parent);
- tree.setHeight(tree.getHeight() + 1);
- //更新
- left.parent = parent;
- right.parent = parent;
- parent.children.add(left);
- parent.children.add(right);
- parent.entries.add(entries.get(leftSize - 1));
- //原来的置空
- entries = null;
- children = null;
- }
- }
- }
-
- /**
- * 删除节点后中间节点的更新
- */
- protected void updateRemove(BPlusTree<K, V> tree) {
-
- // 如果子节点数小于M / 2或者小于2,则需要合并节点
- if (children.size() < tree.getOrder() / 2 || children.size() < 2) {
- if (isRoot) {
- // 如果是根节点并且子节点数大于等于2,无需合并
- if (children.size() >= 2) return;
- // 否则与子节点合并
- //新建根节点
- BPlusNode<K, V> root = children.get(0);
- tree.setRoot(root);
- tree.setHeight(tree.getHeight() - 1);
- root.parent = null;
- root.isRoot = true;
- //原来的置空
- entries = null;
- children = null;
- return;
- }
- //计算前后节点
- //当前结点在父节点的children序列中的位置
- int currIdx = parent.children.indexOf(this);
- int prevIdx = currIdx - 1;
- int nextIdx = currIdx + 1;
- //新建前驱和后继
- BPlusNode<K, V> previous = null, next = null;
- if (prevIdx >= 0) {
- previous = parent.children.get(prevIdx);
- }
- if (nextIdx < parent.children.size()) {
- next = parent.children.get(nextIdx);
- }
-
- // 如果前驱节点子节点数大于M / 2并且大于2,则从其处借补
- if (previous != null
- && previous.children.size() > tree.getOrder() / 2
- && previous.children.size() > 2) {
- //前驱叶子节点末尾节点添加到首位
- int idx = previous.children.size() - 1;
- //新建借的结点
- BPlusNode<K, V> borrow = previous.children.get(idx);
- //借走了,从前驱结点的children序列中移除
- previous.children.remove(idx);
- //借过来了,更新相关
- borrow.parent = this;
- children.add(0, borrow);
- int preIndex = parent.children.indexOf(previous);
-
- entries.add(0, parent.entries.get(preIndex));
- parent.entries.set(preIndex, previous.entries.remove(idx - 1));
- return;
- }
-
- // 同理,如果后继节点子节点数大于M / 2并且大于2,则从其处借补
- if (next != null
- && next.children.size() > tree.getOrder() / 2
- && next.children.size() > 2) {
- //后叶子节点首位添加到末尾
- BPlusNode<K, V> borrow = next.children.get(0);
- next.children.remove(0);
- borrow.parent = this;
- children.add(borrow);
- int preIndex = parent.children.indexOf(this);
- entries.add(parent.entries.get(preIndex));
- parent.entries.set(preIndex, next.entries.remove(0));
- return;
- }
-
- // 如果前驱结点不够借,就同前驱节点合并
- if (previous != null
- && (previous.children.size() <= tree.getOrder() / 2
- || previous.children.size() <= 2)) {
- for (int i = 0; i < children.size(); i++) {
- previous.children.add(children.get(i));
- }
- for (int i = 0; i < previous.children.size(); i++) {
- previous.children.get(i).parent = this;
- }
- int indexPre = parent.children.indexOf(previous);
- previous.entries.add(parent.entries.get(indexPre));
- for (int i = 0; i < entries.size(); i++) {
- previous.entries.add(entries.get(i));
- }
- children = previous.children;
- entries = previous.entries;
-
- //更新父节点的关键字列表
- parent.children.remove(previous);
- previous.parent = null;
- previous.children = null;
- previous.entries = null;
- //合并了,父节点的孩子就少一个
- parent.entries.remove(parent.children.indexOf(this));
- if ((!parent.isRoot
- && (parent.children.size() >= tree.getOrder() / 2
- && parent.children.size() >= 2))
- || parent.isRoot && parent.children.size() >= 2) {
- return;
- }
- //递归调用
- parent.updateRemove(tree);
- return;
- }
-
- // 同理,后继结点不够借,就同后面节点合并
- if (next != null
- && (next.children.size() <= tree.getOrder() / 2
- || next.children.size() <= 2)) {
- for (int i = 0; i < next.children.size(); i++) {
- BPlusNode<K, V> child = next.children.get(i);
- children.add(child);
- child.parent = this;
- }
- int index = parent.children.indexOf(this);
- entries.add(parent.entries.get(index));
- for (int i = 0; i < next.entries.size(); i++) {
- entries.add(next.entries.get(i));
- }
- parent.children.remove(next);
- next.parent = null;
- next.children = null;
- next.entries = null;
- parent.entries.remove(parent.children.indexOf(this));
- if ((!parent.isRoot && (parent.children.size() >= tree.getOrder() / 2
- && parent.children.size() >= 2))
- || parent.isRoot && parent.children.size() >= 2) {
- return;
- }
- parent.updateRemove(tree);
- return;
- }
- }
- }
-
- //在叶子中删除key
- public V remove(K key, BPlusTree<K, V> tree) {
- //如果是叶子节点
- if (isLeaf) {
- //如果不包含该关键字,则直接返回
- if (contains(key) == -1) {
- return null;
- }
- //如果既是叶子节点又是根节点,直接删除
- if (isRoot) {
- if (entries.size() == 1) {
- tree.setHeight(0);
- }
- return remove(key);
- }
- //如果关键字数大于M / 2,直接删除
- if (entries.size() > tree.getOrder() / 2 && entries.size() > 2) {
- return remove(key);
- }
- //如果自身关键字数小于M / 2,并且前驱节点关键字数大于M / 2,则从其处借补
- if (previous != null &&
- previous.parent == parent
- && previous.entries.size() > tree.getOrder() / 2
- && previous.entries.size() > 2) {
- //添加到首位
- int size = previous.entries.size();
- entries.add(0, previous.entries.remove(size - 1));
- int index = parent.children.indexOf(previous);
- parent.entries.set(index, entries.get(0));
- return remove(key);
- }
- //如果自身关键字数小于M / 2,并且后节点关键字数大于M / 2,则从其处借补
- if (next != null
- && next.parent == parent
- && next.entries.size() > tree.getOrder() / 2
- && next.entries.size() > 2) {
- entries.add(next.entries.remove(0));
- int index = parent.children.indexOf(this);
- parent.entries.set(index, next.entries.get(0));
- return remove(key);
- }
-
- //前驱不够借,就同前面节点合并
- if (previous != null
- && previous.parent == parent
- && (previous.entries.size() <= tree.getOrder() / 2
- || previous.entries.size() <= 2)) {
- V returnValue = remove(key);
- for (int i = 0; i < entries.size(); i++) {
- //将当前节点的关键字添加到前节点的末尾
- previous.entries.add(entries.get(i));
- }
- entries = previous.entries;
- parent.children.remove(previous);
- previous.parent = null;
- previous.entries = null;
- //更新链表
- if (previous.previous != null) {
- BPlusNode<K, V> temp = previous;
- temp.previous.next = this;
- previous = temp.previous;
- temp.previous = null;
- temp.next = null;
- } else {
- tree.setHead(this);
- previous.next = null;
- previous = null;
- }
- parent.entries.remove(parent.children.indexOf(this));
- if ((!parent.isRoot && (parent.children.size() >= tree.getOrder() / 2
- && parent.children.size() >= 2))
- || parent.isRoot && parent.children.size() >= 2) {
- return returnValue;
- }
- //父节点要调整
- parent.updateRemove(tree);
- return returnValue;
- }
- //后继结点不够借,就同后面节点合并
- if (next != null
- && next.parent == parent
- && (next.entries.size() <= tree.getOrder() / 2
- || next.entries.size() <= 2)) {
- V returnValue = remove(key);
- for (int i = 0; i < next.entries.size(); i++) {
- //从首位开始添加到末尾
- entries.add(next.entries.get(i));
- }
- next.parent = null;
- next.entries = null;
- parent.children.remove(next);
- //更新链表
- if (next.next != null) {
- BPlusNode<K, V> temp = next;
- temp.next.previous = this;
- next = temp.next;
- temp.previous = null;
- temp.next = null;
- } else {
- next.previous = null;
- next = null;
- }
- //更新父节点的关键字列表
- parent.entries.remove(parent.children.indexOf(this));
- if ((!parent.isRoot && (parent.children.size() >= tree.getOrder() / 2
- && parent.children.size() >= 2))
- || parent.isRoot && parent.children.size() >= 2) {
- return returnValue;
- }
- parent.updateRemove(tree);
- return returnValue;
- }
- }
- /*如果不是叶子节点*/
-
- //如果key小于等于节点最左边的key,沿第一个子节点继续搜索
- if (key.compareTo(entries.get(0).getKey()) < 0) {
- return children.get(0).remove(key, tree);
- //如果key大于节点最右边的key,沿最后一个子节点继续搜索
- } else if (key.compareTo(entries.get(entries.size() - 1).getKey()) >= 0) {
- return children.get(children.size() - 1).remove(key, tree);
- //否则沿比key大的前一个子节点继续搜索
- } else {
- //二分查找
- int low = 0, high = entries.size() - 1, mid = 0;
- int comp;
- while (low <= high) {
- mid = (low + high) / 2;
- comp = entries.get(mid).getKey().compareTo(key);
- if (comp == 0) {
- return children.get(mid + 1).remove(key, tree);
- } else if (comp < 0) {
- low = mid + 1;
- } else {
- high = mid - 1;
- }
- }
- return children.get(low).remove(key, tree);
- }
- }
-
- // 判断当前节点是否包含该关键字
- protected int contains(K key) {
- int low = 0, high = entries.size() - 1, mid;
- int comp;
- while (low <= high) {
- mid = (low + high) / 2;
- comp = entries.get(mid).getKey().compareTo(key);
- if (comp == 0) {
- return mid;
- } else if (comp < 0) {
- low = mid + 1;
- } else {
- high = mid - 1;
- }
- }
- return -1;
- }
-
- // 插入到当前节点的关键字中
- protected void insertOrUpdate(K key, V value) {
- //二叉查找,插入
- int low = 0, high = entries.size() - 1, mid;
- int comp;
- while (low <= high) {
- mid = (low + high) / 2;
- comp = entries.get(mid).getKey().compareTo(key);
- if (comp == 0) {
- entries.get(mid).setValue(value);
- break;
- } else if (comp < 0) {
- low = mid + 1;
- } else {
- high = mid - 1;
- }
- }
- if (low > high) {
- entries.add(low, new AbstractMap.SimpleEntry<K, V>(key, value));
- }
- }
-
- // 返回待删除节点的value值
- protected V remove(K key) {
- int low = 0, high = entries.size() - 1, mid;
- int comp;
- while (low <= high) {
- mid = (low + high) / 2;
- comp = entries.get(mid).getKey().compareTo(key);
- if (comp == 0) {
- return entries.remove(mid).getValue();
- } else if (comp < 0) {
- low = mid + 1;
- } else {
- high = mid - 1;
- }
- }
- return null;
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("isRoot: ");
- sb.append(isRoot);
- sb.append(", ");
- sb.append("isLeaf: ");
- sb.append(isLeaf);
- sb.append(", ");
- sb.append("keys: ");
- for (Map.Entry<K, V> entry : entries) {
- sb.append(entry.getKey());
- sb.append(", ");
- }
- sb.append(", ");
- return sb.toString();
- }
-
- //打印信息
- public void printBPlusTree(int index) {
- if (this.isLeaf) {
- System.out.print("层级:" + index + ",叶子节点,keys为: ");
- for (int i = 0; i < entries.size(); ++i)
- System.out.print(entries.get(i) + " ");
- System.out.println();
- } else {
- System.out.print("层级:" + index + ",非叶子节点,keys为: ");
- for (int i = 0; i < entries.size(); ++i)
- System.out.print(entries.get(i) + " ");
- System.out.println();
- for (int i = 0; i < children.size(); ++i)
- children.get(i).printBPlusTree(index + 1);
- }
- }
- }
-
BPlusTree.java
- package BplusTree;
-
- /**
- * B+树的定义:
- * 1.任意非叶子结点最多有M个子节点;且M>2;M为B+树的阶数
- * 2.除根结点以外的非叶子结点至少有 (M+1)/2个子节点;
- * 3.根结点至少有2个子节点;
- * 4.除根节点外每个结点存放至少(M-1)/2和至多M-1个关键字;(至少1个关键字)
- * 5.非叶子结点的子树指针比关键字多1个;
- * 6.非叶子节点的所有key按升序存放,假设节点的关键字分别为K[0], K[1] … K[M-2],指向子女的指针分别为P[0], P[1]…P[M-1]。则有:
- * P[0] < K[0] <= P[1] < K[1] …..< K[M-2] <= P[M-1]
- * 7.所有叶子结点位于同一层;
- * 8.为所有叶子结点增加一个链指针;
- * 9.所有关键字都在叶子结点出现
- */
-
- @SuppressWarnings("all")
- public class BPlusTree<K extends Comparable<K>, V> {
-
- // 根节点
- protected BPlusNode<K, V> root;
-
- // 每个空间最多可以存多少数据
- protected int order;
-
- // 叶子节点的链表头
- protected BPlusNode<K, V> head;
-
- // 树高
- protected int height = 0;
-
- public BPlusNode<K, V> getHead() {
- return head;
- }
-
- public void setHead(BPlusNode<K, V> head) {
- this.head = head;
- }
-
- public BPlusNode<K, V> getRoot() {
- return root;
- }
-
- public void setRoot(BPlusNode<K, V> root) {
- this.root = root;
- }
-
- public int getOrder() {
- return order;
- }
-
- public void setOrder(int order) {
- this.order = order;
- }
-
- public void setHeight(int height) {
- this.height = height;
- }
-
- public int getHeight() {
- return height;
- }
-
- public V query(K key) {return root.query(key);}
-
- public V remove(K key) {
- return root.remove(key, this);
- }
-
- public void insertOrUpdate(K key, V value) {
- root.insertOrUpdate(key, value, this);
- }
-
- public BPlusTree(int order) {
- if (order < 3) {
- System.out.print("度数要大于2!");
- System.exit(0);
- }
- this.order = order;
- root = new BPlusNode<K, V>(true, true);
- head = root;
- }
-
- public void printBPlusTree() {
- this.root.printBPlusTree(0);
- }
- }
-
BPlusTreeTest.java
- package BplusTree;
-
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Random;
-
- public class BPlusTreeTest {
- // 测试
- public static void main(String[] args) {
- int size = 12;
- int order = 4;
- testRandomInsert(size, order);
- //testRandomSearch(size, order);
- //testRandomRemove(size, order);
- }
-
- private static void testRandomRemove(int size, int order) {
- BPlusTree<Integer, Integer> tree = new BPlusTree<Integer, Integer>(order);
- System.out.println("\nTest random remove " + size + " datas, of order:"
- + order);
- Random random = new Random();
- boolean[] a = new boolean[size + 10];
- List<Integer> list = new ArrayList<Integer>();
- int randomNumber = 0;
- System.out.println("Begin random insert...");
- for (int i = 0; i < size; i++) {
- randomNumber = random.nextInt(size);
- a[randomNumber] = true;
- list.add(randomNumber);
- tree.insertOrUpdate(randomNumber, randomNumber);
- }
- tree.printBPlusTree();
- System.out.println("Begin random remove...");
- long current = System.currentTimeMillis();
- for (int j = 0; j < size; j++) {
- randomNumber = list.get(j);
- if (a[randomNumber]) {
- if (tree.remove(randomNumber) == null) {
- System.err.println("得不到数据:" + randomNumber);
- break;
- } else {
- a[randomNumber] = false;
- }
- }
- }
- long duration = System.currentTimeMillis() - current;
- System.out.println("time elpsed for duration: " + duration);
- tree.printBPlusTree();
- System.out.println("树高:"+tree.getHeight());
- }
-
- private static void testRandomSearch(int size, int order) {
- BPlusTree<Integer, Integer> tree = new BPlusTree<Integer, Integer>(order);
- System.out.println("\nTest random search " + size + " datas, of order:"
- + order);
- Random random = new Random();
- boolean[] a = new boolean[size + 10];
- int randomNumber = 0;
- System.out.println("Begin random insert...");
- for (int i = 0; i < size; i++) {
- randomNumber = random.nextInt(size);
- a[randomNumber] = true;
- tree.insertOrUpdate(randomNumber, randomNumber);
- }
- tree.printBPlusTree();
- System.out.println("Begin random search...");
- long current = System.currentTimeMillis();
- for (int j = 0; j < size; j++) {
- randomNumber = random.nextInt(size);
- if (a[randomNumber]) {
- if (tree.query(randomNumber) == null) {
- System.err.println("得不到数据:" + randomNumber);
- break;
- }
- }
- }
- long duration = System.currentTimeMillis() - current;
- System.out.println("time elpsed for duration: " + duration);
- }
-
- private static void testRandomInsert(int size, int order) {
- BPlusTree<Integer, Integer> tree = new BPlusTree<Integer, Integer>(order);
- System.out.println("\nTest random insert " + size + " datas, of order:"
- + order);
- Random random = new Random();
- int randomNumber = 0;
-
- for (int i = 0; i < size; i++) {
- randomNumber = random.nextInt(size * 10);
- System.out.print(randomNumber + " ");
- tree.insertOrUpdate(randomNumber, randomNumber);
- }
-
- tree.printBPlusTree();
- System.out.println("树高:"+tree.getHeight());
- }
- }
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。