package CH18;
import java.util.Spliterator;
import javax.enterprise.inject.New;
import CH18.Btree3.BTreeNode;
import sun.net.www.content.text.plain;
public class BTREE<Key extends Comparable<Key>, Value> {
// m阶,节点最多M个,关键字最多M-1
private static int MAX_CHILDS_NUM = 5;
// 节点最少MIN_KEY_NUM个,关键字最少MIN_KEY_NUM
private static int MIN_CHILDS_NUM = (int) Math.ceil(MAX_CHILDS_NUM / 2.0);
private static int MIN_KEYS_NUM = MIN_CHILDS_NUM - 1;
private static int MAX_KEYS_NUM = MAX_CHILDS_NUM - 1;
private static int MIN_DELETE_KEY_NUM = MAX_CHILDS_NUM;
private int height = 0;
private Node root;
private static class ReturnVo {
private Node lt;
private Node gt;
private Entry data;
public ReturnVo(Node lt, Node gt, Entry data) {
super();
this.lt = lt;
this.gt = gt;
this.data = data;
}
}
private final static class Node {
private Node parent;
private int num;
// 0号负责占位,留一个备用,M-1个为合理key
private Entry[] datas = new Entry[MAX_KEYS_NUM + 2];
public Node(int i) {
num = i;
}
// 一个备用个为合理key
Node[] childs = new Node[MAX_CHILDS_NUM + 1];
}
private static class Entry {
private Comparable key;
private Object value;
public Entry(Comparable key, Object value) {
super();
this.key = key;
this.value = value;
}
}
private boolean eq(Comparable key1, Comparable key2) {
return key1.compareTo(key2) == 0;
}
private boolean less(Comparable key1, Comparable key2) {
return key1.compareTo(key2) < 0;
}
private boolean notlarger(Comparable key1, Comparable key2) {
return key1.compareTo(key2) <= 0;
}
public void put(Key key, Value value) {
System.out.println(key + "开始插入");
Entry entry = new Entry(key, value);
if (root == null) {
root = new Node(1);
root.childs = null;
root.datas[1] = entry;
return;
}
ReturnVo rootVo = insertEntry(root, entry, height);
if (rootVo != null) {
System.out.println(key + "需要分裂");
root = new Node(1);
root.datas[1] = rootVo.data;
root.childs[0] = rootVo.lt;
root.childs[1] = rootVo.gt;
height++;
}
System.out.println(key + "完成插入");
}
public void remove(Node node, Comparable key, int hv) {
int j = 1;
while (j <= node.num) {
if (notlarger(key, node.datas[j].key)) {
break;
}
j++;
}
if (hv == 0) {
if (eq(node.datas[j].key, key)) {
deleteLeafnode(node, j);
}else {
System.out.println("没找到该值key:"+key);
}
}else {
if(eq(node.datas[j].key, key)){
deleteNonleafnode(node, j,hv);
return;
}
boolean flag = (j-1 == node.num);
if(node.childs[j-1].num<MIN_DELETE_KEY_NUM){
fill(node,j-1,hv);
}
if (flag && j-1 > node.num)
//fill里的向前合并起了作用,导致j需要调整,
remove(node.childs[j-2], key, hv-1);
else
remove(node.childs[j-1], key, hv-1);
}
}
/**
* 借东西,
* @param node
* @param j
*/
private void fill(Node node, int j,int hv) {
if(j>0&&node.childs[j-1].num>=MIN_DELETE_KEY_NUM){
borrowFromPrev(node,j,hv);
}else if(j<MAX_CHILDS_NUM-1&&node.childs[j+1].num>=MIN_DELETE_KEY_NUM){
borrowFromNext(node, j, hv);
}else if(node.num != j){
merge(node,j,hv);
}else {
merge(node,j-1,hv);
}
}
/**
* 兄弟间 合作,父节点减少一个key
* @param node
* @param i
* @param hv
*
* before:
* node child:c2 sibling:c3
* null|10|20|30| null|15|18| null|24|26|
* c1|c2|c3|c4| q1|q2|q3| z1|z2|z3|
*
* after:
* node child:c2 sibling:c3
* null|10|30| null|15|18|20|24|26| null
* c1|c2|c4| |q1|q2|q3|z1|z2|z3|
*
*/
private void merge(Node node, int j, int hv) {
Node child = node.childs[j];
Node sibling = node.childs[j+1];
for(int l6=1;l6<=sibling.num;l6++){
child.datas[MIN_DELETE_KEY_NUM+l6] = sibling.datas[l6];
}
child.datas[MIN_DELETE_KEY_NUM] = node.datas[j+1];
for(int ni=j+1;ni<node.num;ni++){
node.datas[ni] = node.datas[ni+1];
}
node.datas[node.num]=null;
if(hv>0){
for(int l7=0;l7<=sibling.num;l7++){
child.childs[MIN_DELETE_KEY_NUM+l7] = sibling.childs[l7];
}
for(int n2=j+1;n2<node.num;n2++){
node.childs[n2] = node.childs[n2+1];
}
node.childs[node.num]=null;
}
if(hv == height){
height--;
}
node.num--;
child.num += sibling.num+1;
}
/**
* 真儿子找他的干哥哥借
* @param node
* @param j
* @param hv
*
* before:
* node child:c2 sibling:c3
* null|10|20|30| null|15|18| null|24|26|28|
* c1|c2|c3|c4| q1|q2|q3| z1|z2|z3|z4|
*
* after:
* node child:c2 sibling:c3
* null|10|24|30| null|15|18|20| null|26|28|
* c1|c2|c3|c4| |q1|q2|q3|z1| z2|z3|z4|
*
*/
private void borrowFromNext(Node node, int j, int hv) {
Node child = node.childs[j];
Node sibling = node.childs[j+1];
child.datas[child.num+1] = node.datas[j+1];
node.datas[j+1] = sibling.datas[1];
for(int l3=1;l3<=child.num;l3++){
sibling.datas[l3-1] = sibling.datas[l3];
}
sibling.datas[child.num]=null;
if(hv>0){
for(int l4=1;l4<=child.num;l4++){
sibling.childs[l4-1] = sibling.childs[l4];
}
sibling.childs[sibling.num]=null;
child.childs[child.num+1] = sibling.childs[0];
}
}
/**
* 真儿子找他的干弟弟借
* @param node
* @param j,child的位置
* @param hv
*
* before:
* node child:c2 sibling:c1
* null|10|20|30| null|15|18| null|04|06|08|
* c1|c2|c3|c4| q1|q2|q3| z1|z2|z3|z4|
*
* after:
* node child:c2 sibling:c1
* null|08|20|30| null|10|15|18| null|04|06|
* c1|c2|c3|c4| z4|q1|q2|q3| z1|z2|z3|
*
*/
void borrowFromPrev(Node node,int j,int hv) {
Node child = node.childs[j];
Node sibling = node.childs[j-1];
for(int l2=child.num;l2>0;l2--){
child.datas[l2+1] = child.datas[l2];
}
child.datas[1] = node.datas[j];
node.datas[j]= sibling.datas[sibling.num];
if(hv > 0){
for(int l3=child.num;l3>=0;l3--){
child.childs[l3+1] = child.childs[l3];
}
child.childs[0] = sibling.childs[sibling.num];
}
child.num++;
sibling.datas[sibling.num]=null;
sibling.childs[sibling.num]=null;
sibling.num--;
}
/**
* 删除叶子节点
* @param node
* @param j
*/
private void deleteLeafnode(Node node,int j){
for (int l1 = j; l1 < node.num; l1++) {
node.datas[l1] = node.datas[l1 + 1];
}
node.num--;
node.datas[node.num]=null;
}
/**
* 删除非叶子节点
*/
private void deleteNonleafnode(Node node,int j,int hv){
if(node.childs[j-1].num>=MIN_DELETE_KEY_NUM){
Entry pred = getPred(node,j,hv);
node.datas[j] = pred;
remove(node.childs[j-1],pred.key, hv-1);
}else if(node.childs[j].num>=MIN_CHILDS_NUM){
Entry succ = getSucc(node,j,hv);
node.datas[j+1] = succ;
remove(node.childs[j],succ.key, hv-1);
}else {
merge(node, j-1, hv);
remove(node.childs[j-1],node.datas[j].key, hv-1);
}
}
private Entry getSucc(Node node, int j, int hv) {
Node cur = node.childs[j-1];
hv--;
while(hv!=0){
cur = cur.childs[0];
hv--;
}
return cur.datas[1];
}
private Entry getPred(Node node,int j,int hv) {
Node cur = node.childs[j-1];
hv--;
while (hv!=0) {
cur = cur.childs[cur.num];
hv--;
}
return cur.datas[cur.num];
}
private ReturnVo insertEntry(Node node, Entry entry, int hv) {
int j = 1;
while (j <= node.num) {
if (less(entry.key, node.datas[j].key)) {
break;
}
if (eq(entry.key, node.datas[j].key)) {
node.datas[j].value = entry.value;
return null;
}
j++;
}
// leaf
if (hv == 0) {
for (int l1 = node.num; l1 >= j; l1--) {
node.datas[l1 + 1] = node.datas[l1];
}
node.datas[j] = entry;
node.num++;
} else {
ReturnVo revo = insertEntry(node.childs[j - 1], entry, hv - 1);
if (revo == null) {
return null;
}
// 补上下层传来的child指向的变更和entry
for (int k1 = node.num; k1 >= j; k1--) {
node.childs[k1 + 1] = node.childs[k1];
node.datas[k1 + 1] = node.datas[k1];
}
node.childs[j - 1] = revo.lt;
node.childs[j] = revo.gt;
node.datas[j] = revo.data;
}
if (node.num > MAX_KEYS_NUM) {
return split(node);
} else {
return null;
}
}
// 包含需提升至父节点的entry
private ReturnVo split(Node h) {
Node lt = new Node(MIN_KEYS_NUM);
Node gt = new Node(MIN_KEYS_NUM);
/*
* null|02|10|20|30|50| --->null|02|10| + null|30|50| E1|E2|E3|E4|E5|E6|
* E1|E2|E3| E4|E5|E6|
*/
System.arraycopy(h.datas, 1, lt.datas, 1, MIN_KEYS_NUM);
System.arraycopy(h.datas, MIN_KEYS_NUM + 2, gt.datas, 1, MIN_KEYS_NUM);
if (h.childs != null) {
System.arraycopy(h.childs, 0, lt.childs, 0, MIN_CHILDS_NUM);
System.arraycopy(h.childs, MIN_CHILDS_NUM, gt.childs, 0, MIN_CHILDS_NUM);
}
ReturnVo vo = new ReturnVo(lt, gt, h.datas[MIN_KEYS_NUM + 1]);
return vo;
}
public static void main(String[] args) {
BTREE<Integer, Integer> btree = new BTREE<Integer, Integer>();
btree.put(1, 1);
btree.put(11, 11);
btree.put(8, 8);
btree.put(10, 10);
btree.put(12, 12);
btree.put(9, 9);
btree.put(2, 2);
btree.put(3, 3);
btree.put(6, 6);
btree.put(1, 1);
btree.put(4, 4);
}
}
BTree的基本操作
猜你喜欢
转载自blog.csdn.net/zharen351991/article/details/80136512
今日推荐
周排行