package com.algorithm.tree;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class BTree<T extends Comparable<T>> {
public int minDgree;
public int keynum;
public T[] key;
public ArrayList<BTree<T>> child;
public boolean isLeaf;
public BTree(){
}
public BTree(T[] array,int minDegree){
BTree<T> btree=new BTree<T>();
btree.isLeaf=true;
btree.minDgree=minDegree;
btree.keynum=0;
btree.key=(T[])Array.newInstance(array.getClass().getComponentType(), 2*minDegree-1);
Arrays.fill(btree.key, 0); /*使用反射得到的数组填充一下再使用,省略此处会产生NullPointerException*/
btree.child=new ArrayList<BTree<T>>(2*minDegree);
/*Collections.fill(btree.child, null);使用此方法不会改变size()大小,换句话说此方法填充的元素数量取决于size()而不是capacity()!!!!*/
for(int i=0;i<2*minDegree;i++){
btree.child.add(null);
}
int i=1;
for(T ele:array){
btree=insert(btree,ele);
System.out.println("初始化第"+i+++"个节点");
keynum=btree.keynum;
isLeaf=btree.isLeaf;
key=btree.key;
child=btree.child;
this.minDgree=minDegree;
}
}
public static <T extends Comparable<T>> void split(BTree<T> parent,int i){
BTree<T> first=parent.child.get(i);
BTree<T> second=new BTree<>();
second.minDgree=parent.minDgree;
second.isLeaf=first.isLeaf;
second.key=(T[])Array.newInstance(parent.key.getClass().getComponentType(), 2*parent.minDgree-1);
second.child=new ArrayList<BTree<T>>(2*parent.minDgree);
for(int k=0;k<2*parent.minDgree;k++){
second.child.add(null);
}
int j=parent.minDgree;
int m=0;
while(j<first.keynum){
second.key[m]=first.key[j];
second.child.set(m++, first.child.get(j++));
}
second.child.set(m, first.child.get(j));
first.keynum=second.keynum=parent.minDgree-1;
j=parent.keynum-1;
while(j>=i){
parent.key[j+1]=parent.key[j];
if(j!=i) parent.child.set(j+1, parent.child.get(j));
j--;
}
parent.key[i]=first.key[parent.minDgree-1];
parent.keynum++;
parent.child.set(i+1, second);
System.out.println("fenliehou keynum"+parent.keynum+"zhiwei"+parent.key[i]+"i wei"+i);
}
public static <T extends Comparable<T>> BTree<T> insert(BTree<T> root,T ele){
if(root==null) return null;
if(root.keynum==(2*root.minDgree-1)){
BTree newRoot=new BTree();
newRoot.minDgree=root.minDgree;
newRoot.isLeaf=false;
newRoot.key=(T[])Array.newInstance(root.key.getClass().getComponentType(), Array.getLength(root.key));
Arrays.fill(newRoot.key, 0);
newRoot.keynum=0;
newRoot.child=new ArrayList<T>(Array.getLength(root.key)+1);
for(int i=0;i<2*newRoot.minDgree;i++){
newRoot.child.add(null);
}
newRoot.child.set(0, root);
split(newRoot,0);
insertNonfull(newRoot,ele);
return newRoot;
}else{
insertNonfull(root,ele);
return root;
}
}
public static <T extends Comparable<T>> void insertNonfull(BTree<T> p,T ele){
T[] newArray=(T[])Arrays.copyOf(p.key, p.keynum);
int i=Arrays.binarySearch(newArray, ele);
int insertionPoint=-(i+1);
if(i<0 && !p.isLeaf){
if(p.child.get(insertionPoint).keynum==(2*p.minDgree-1)){
split(p,insertionPoint);
insertionPoint=ele.compareTo(p.key[insertionPoint])>0 ? (insertionPoint+1):insertionPoint;
}
insertNonfull(p.child.get(insertionPoint),ele);
}
if(i<0 && p.isLeaf){
int j=p.keynum-1;
while(j>=insertionPoint){
p.key[j+1]=p.key[j];
j--;
}
p.key[insertionPoint]=ele;
System.out.println("cha ru ele"+ele+"wei zhi"+insertionPoint+"jie dian"+p+"keynum"+p.keynum);
p.keynum++;
}
}
public boolean search(T k){
T[] array=Arrays.copyOf(key, keynum);
int i=Arrays.binarySearch(array, k);/*NullPointerException null不能参与比较大小 */
if(i>=0) return true;
if(isLeaf) return false;
int insertionPoint=-(i+1);
return child.get(insertionPoint).search(k);
}
public void traverse(){
int i;
for(i=0;i<keynum;i++){
if(child.get(i)!=null) child.get(i).traverse();
System.out.print(key[i]+",");
}
if(child.get(i)!=null) child.get(i).traverse();
}
public static void main(String[] args){
BTree<Integer> btree=new BTree<Integer>(new Integer[]{1,2,3,4,5,6,7,8,9,10,11,12,13},3);
btree.traverse();
boolean b1=btree.search(12);
boolean b2=btree.search(49);
System.out.println("\nb1 : "+b1+" b2 : "+b2);
}
}
输出结果:
cha ru ele1wei zhi0jie diancom.algorithm.tree.BTree@17e121ckeynum0
初始化第1个节点
cha ru ele2wei zhi1jie diancom.algorithm.tree.BTree@17e121ckeynum1
初始化第2个节点
cha ru ele3wei zhi2jie diancom.algorithm.tree.BTree@17e121ckeynum2
初始化第3个节点
cha ru ele4wei zhi3jie diancom.algorithm.tree.BTree@17e121ckeynum3
初始化第4个节点
cha ru ele5wei zhi4jie diancom.algorithm.tree.BTree@17e121ckeynum4
初始化第5个节点
fenliehou keynum1zhiwei3i wei0
cha ru ele6wei zhi2jie diancom.algorithm.tree.BTree@1d6f122keynum2
初始化第6个节点
cha ru ele7wei zhi3jie diancom.algorithm.tree.BTree@1d6f122keynum3
初始化第7个节点
cha ru ele8wei zhi4jie diancom.algorithm.tree.BTree@1d6f122keynum4
初始化第8个节点
fenliehou keynum2zhiwei6i wei1
cha ru ele9wei zhi2jie diancom.algorithm.tree.BTree@7109c4keynum2
初始化第9个节点
cha ru ele10wei zhi3jie diancom.algorithm.tree.BTree@7109c4keynum3
初始化第10个节点
cha ru ele11wei zhi4jie diancom.algorithm.tree.BTree@7109c4keynum4
初始化第11个节点
fenliehou keynum3zhiwei9i wei2
cha ru ele12wei zhi2jie diancom.algorithm.tree.BTree@1385660keynum2
初始化第12个节点
cha ru ele13wei zhi3jie diancom.algorithm.tree.BTree@1385660keynum3
初始化第13个节点
1,2,3,4,5,6,7,8,9,10,11,12,13,
b1 : true b2 : false