java實現B-Tree
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 [email protected]
初始化第1個節點
cha ru ele2wei zhi1jie [email protected]
初始化第2個節點
cha ru ele3wei zhi2jie [email protected]
初始化第3個節點
cha ru ele4wei zhi3jie [email protected]
初始化第4個節點
cha ru ele5wei zhi4jie [email protected]
初始化第5個節點
fenliehou keynum1zhiwei3i wei0
cha ru ele6wei zhi2jie
初始化第6個節點
cha ru ele7wei zhi3jie [email protected]
初始化第7個節點
cha ru ele8wei zhi4jie [email protected]
初始化第8個節點
fenliehou keynum2zhiwei6i wei1
cha ru ele9wei zhi2jie [email protected]
初始化第9個節點
cha ru ele10wei zhi3jie [email protected]
初始化第10個節點
cha ru ele11wei zhi4jie
初始化第11個節點
fenliehou keynum3zhiwei9i wei2
cha ru ele12wei zhi2jie [email protected]
初始化第12個節點
cha ru ele13wei zhi3jie [email protected]
初始化第13個節點
1,2,3,4,5,6,7,8,9,10,11,12,13,
b1 : true b2 : false