import java.util.ArrayList;
import java.util.List;
public class BTree<Key extends Comparable<Key>, Value> {
private Node root;
private int Max, //最大分支数,最大节点数
Min_len; //最小节点数
private BTree(int m) { //m为B树阶数
Max = m;
Min_len = (m + 1) / 2 - 1;
}
private class Factor {
private Key key;
private Value val;
private Factor(Key key, Value val) {
this.key = key;
this.val = val;
}
}
@SuppressWarnings("unchecked")
private class Node {
private ArrayList<Factor> factors;
private ArrayList<Node> branchs;
private Node parent;
private Node(Factor factor, Node parent) {
this.factors = new ArrayList<Factor>();
this.branchs = new ArrayList<Node>();
this.factors.add(factor);
this.parent = parent;
}
private Node(List<Factor> factors, Node parent) {
this.factors = new ArrayList<Factor>(factors);
this.branchs = new ArrayList<Node>();
this.parent = parent;
}
}
private void LevelOrder() {
int h = 0;
ArrayList<Node> t = new ArrayList<Node>();
t.add(root);
while (t.size() != 0) {
int size = t.size();
h++;
System.out.println("第 " + h + " 层");
for (int i = 0; i < size; i++) {
System.out.println(" 节点" + (i + 1) + ": ");
Node temp = t.get(0);
for (Factor f : temp.factors)
System.out.print(" " + f.key + " ");
System.out.println("\n");
t.addAll(temp.branchs);
t.remove(0);
}
}
}
private boolean HasChild(Node node) {
return !node.branchs.isEmpty();
}
private boolean isRoot(Node node) {
return node.parent == null;
}
private boolean isOverFlow(Node node) {
return node.factors.size() == Max;
}
private boolean isUnderFlow(Node node) {
if (node.parent != null)
return node.factors.size() < Min_len;
return false;
}
private boolean isCritical(Node node) {
return node.factors.size() < Min_len || node.factors.size() == Min_len;
}public ArrayList<Factor> Search(Key key) {
return SearchIn(root, key);
}
private ArrayList<Factor> SearchIn(Node temp, Key key) {
if (temp == null)
return null;
int t = 0;
for (; t < temp.factors.size(); t++) {
int cmp = key.compareTo(temp.factors.get(t).key);
if (cmp < 0)
return SearchIn(temp.branchs.get(t), key);
else if (cmp == 0) {
return temp.factors;
}
}
return SearchIn(temp.branchs.get(temp.branchs.size() - 1), key);
}
public void Insert(Key key, Value val) {
if (root == null) { //if this tree is empty
root = new Node(new Factor(key, val), null);//insert a new node then return
return;
}
Node temp = root; //temp is a copy of root
while (true) {
int t = 0, size = temp.factors.size();
for (; t < size; t++) { //循环遍历temp的所有factor元素
int cmp = key.compareTo(temp.factors.get(t).key);//将待插入节点与temp当前所指factor的key值作比较
if (cmp < 0) { //当待插入Key值小于temp所指Key值时执行下面语句
if (!temp.branchs.isEmpty()) { //如果待插入位置存在分支
temp = temp.branchs.get(t); //则继续向子node处移动然后继续比较
break;
} else { //若没有分支
temp.factors.add(t, (new Factor(key, val)));//在此位置插入新node
if (isOverFlow(temp)) //若temp存在上溢,更新节点
UpdateTreeOverFlow(temp);
return;
}
} else if (cmp == 0) {
temp.factors.get(t).val = val;
return;
}
}
if (t == size)
if (!temp.branchs.isEmpty())
temp = temp.branchs.get(temp.branchs.size() - 1); //WARNING!!!!!!!!!!
else {
temp.factors.add(new Factor(key, val));
if (isOverFlow(temp))
UpdateTreeOverFlow(temp);
return;
}
}
}
private void UpdateTreeOverFlow(Node temp) { //注:sublist是左闭右开的,例:sublist(0,4)包含了0,1,2,3没有4.
int po = Max / 2;//求出中位数位置(向下取整)
if (temp.parent == null) {//若待更新节点没有爸爸(which mean he is an 孤儿,哈哈哈哈哈哈)
Node t = new Node(temp.factors.get(po), null); //new一个节点 t 做爸爸
t.branchs.add(new Node(temp.factors.subList(0, po), null));//为t新建一个左孩子
Node left_child = t.branchs.get(0);
temp.factors.subList(0, po + 1).clear();//将原来的temp节点中包括中位数以左的所有元素清除
temp.parent = t;
left_child.parent = t;
t.branchs.add(temp);
if (HasChild(temp)) {//若原待更新节点的有孩子(是孤儿,可是有自己的孩子)
left_child.branchs.addAll(temp.branchs.subList(0, po + 1));//把自己的孩子分一半给自己新找的兄弟
for (Node x : left_child.branchs)//让这些孩子叫新兄弟爸爸
x.parent = left_child;
temp.branchs.subList(0, po + 1).clear();//把原来自己户口下的孩子(现在已经送给自己的新兄弟了)删掉
}
root = t;
} else { //若待更新节点有爸爸
Node parent = temp.parent; //新建一个临时变量parent指向待更新节点的爸爸
Factor mid = temp.factors.get(po); //mid为待更新节点所有元素的中间元素
int i = 0,
FactorSize_parent = parent.factors.size(),
FactorSize_temp = temp.factors.size();
for (; i < FactorSize_parent; i++) //选取mid插入位置
if (mid.key.compareTo(parent.factors.get(i).key) < 0) {//当mid的值小于parents[i]时插入
parent.factors.add(i, mid);
parent.branchs.add(i + 1, new Node(temp.factors.subList(po + 1, FactorSize_temp), parent));
Node right_node = parent.branchs.get(i + 1);
temp.factors.subList(po, FactorSize_temp).clear();
if (HasChild(temp)) {
right_node.branchs.addAll(temp.branchs.subList(po + 1, temp.branchs.size()));
for (Node x : right_node.branchs)//让这些孩子叫新兄弟爸爸
x.parent = right_node;
temp.branchs.subList(po + 1, temp.branchs.size()).clear();
}
if (isOverFlow(parent))
UpdateTreeOverFlow(parent);
return;
}
parent.factors.add(mid); //子节点的mid插入到父节点最后面的情形
parent.branchs.add(new Node(temp.factors.subList(po + 1, FactorSize_temp), parent));
Node right_node = parent.branchs.get(parent.branchs.size() - 1);//WARNING!!!!!
temp.factors.subList(po, FactorSize_temp).clear();
if (HasChild(temp)) {
right_node.branchs.addAll(temp.branchs.subList(po + 1, temp.branchs.size()));
for (Node x : right_node.branchs)//让这些孩子叫新兄弟爸爸
x.parent = right_node;
temp.branchs.subList(po + 1, temp.branchs.size()).clear();
}
if (isOverFlow(parent))
UpdateTreeOverFlow(parent);
}
}
public void Remove(Key key) {
Node temp = root;
while (true) {
int i = 0;
int size = temp.factors.size();
for (; i < size; i++) {
int cmp = key.compareTo(temp.factors.get(i).key);
if (cmp == 0) {
if (HasChild(temp)) {
Factor temp_f = temp.factors.get(i);
Node t = GetSuccessor(temp.branchs.get(i + 1));
Factor x = t.factors.get(0);
temp_f.key = x.key;
temp_f.val = x.val;
temp = t;
temp.factors.remove(0);
if (isUnderFlow(temp))
UpdateTreeUnderFlow(temp);
return;
}
temp.factors.remove(i);
if (isUnderFlow(temp))
UpdateTreeUnderFlow(temp);
return;
} else if (cmp < 0) {
if (HasChild(temp)) {
temp = temp.branchs.get(i);
break;
} else {
throw new IndexOutOfBoundsException("树中无此值");
}
}
}
if (i == size) {
if (HasChild(temp)) {
temp = temp.branchs.get(temp.branchs.size() - 1);
} else {
return;
}
}
}
}
private Node GetSuccessor(Node temp) {
while (!temp.branchs.isEmpty())
temp = temp.branchs.get(0);
return temp;
}
private void UpdateTreeUnderFlow(Node temp) {
Node parent = temp.parent;
int i = 0;
for (; i < parent.branchs.size(); i++)
if (parent.branchs.get(i) == temp)
break;
if (i == parent.branchs.size())
i--;
if (i == 0 && !isCritical(parent.branchs.get(1))) { //i==0即temp在最左边,isCritical判断这个节点是否处在临界状态
Node right_bro = parent.branchs.get(1);
Factor parent_fac = parent.factors.get(0);
temp.factors.add(new Factor(parent_fac.key, parent_fac.val));
parent_fac.key = right_bro.factors.get(0).key;
parent_fac.val = right_bro.factors.get(0).val;
right_bro.factors.remove(0);
if (HasChild(right_bro)) {
temp.branchs.add(right_bro.branchs.get(0));
temp.branchs.get(temp.branchs.size() - 1).parent = temp;
right_bro.branchs.remove(0);
}
} else if (i != 0 && (!isCritical(parent.branchs.get(i - 1)) ||
(i + 1 < parent.branchs.size() && !isCritical(parent.branchs.get(i + 1))))) { //temp不在最左边的情况
if (!isCritical(parent.branchs.get(i - 1))) {//先看左兄弟
Node left_bro = parent.branchs.get(i - 1);
Factor parent_fac = parent.factors.get(i - 1);
temp.factors.add(0, new Factor(parent_fac.key, parent_fac.val));
parent_fac.key = left_bro.factors.get(left_bro.factors.size() - 1).key;
parent_fac.val = left_bro.factors.get(left_bro.factors.size() - 1).val;
left_bro.factors.remove(left_bro.factors.size() - 1);
if (HasChild(left_bro)) {
temp.branchs.add(0, left_bro.branchs.get(left_bro.branchs.size() - 1));
temp.branchs.get(0).parent = temp;
left_bro.branchs.remove(left_bro.branchs.size() - 1);
}
} else {//看右兄弟
Node right_bro = parent.branchs.get(i + 1);
Factor parent_fac = parent.factors.get(i);
temp.factors.add(new Factor(parent_fac.key, parent_fac.val));
parent_fac.key = right_bro.factors.get(0).key;
parent_fac.val = right_bro.factors.get(0).val;
right_bro.factors.remove(0);
if (HasChild(right_bro)) {
temp.branchs.add(right_bro.branchs.get(0));
temp.branchs.get(temp.branchs.size() - 1).parent = temp;
right_bro.branchs.remove(0);
}
}
} else {
if (parent.factors.size() == 1) {//当父节点元素只有一个的时候
parent.factors.addAll(0, parent.branchs.get(0).factors);
parent.factors.addAll(parent.branchs.get(1).factors);
if (HasChild(parent.branchs.get(0)))
parent.branchs.addAll(parent.branchs.get(0).branchs);
if (HasChild(parent.branchs.get(1)))
parent.branchs.addAll(parent.branchs.get(1).branchs);
parent.branchs.remove(0);
parent.branchs.remove(0);
for (Node t : parent.branchs)
t.parent = parent;
} else {
if (i == 0) {
temp.factors.add(parent.factors.get(0));
temp.factors.addAll(parent.branchs.get(1).factors);
if (HasChild(parent.branchs.get(1))) {
int size = temp.branchs.size();
temp.branchs.addAll(parent.branchs.get(1).branchs);
for (; size < temp.branchs.size(); size++)
temp.branchs.get(size).parent = temp;
}
parent.branchs.remove(1);
parent.factors.remove(0);
} else {
Node left_bro = parent.branchs.get(i - 1);
left_bro.factors.add(parent.factors.get(i - 1));
left_bro.factors.addAll(temp.factors);
if (HasChild(temp)) {
int size = left_bro.branchs.size();
left_bro.branchs.addAll(temp.branchs);
for (; size < left_bro.branchs.size(); size++)
left_bro.branchs.get(size).parent = left_bro;
}
parent.factors.remove(i - 1);
parent.branchs.remove(temp);
}
}
}
if (isUnderFlow(parent))
UpdateTreeUnderFlow(parent);
}
public static void main(String args[]) {
ArrayList<Integer> z = new ArrayList<Integer>();
// try {
// FileReader fw = new FileReader("/home/innovation/文档/number");
// BufferedReader br = new BufferedReader(fw);
// String x = null;
// while ((x = br.readLine()) != null)
// z.add(Integer.parseInt(x));
// fw.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
for (int i = 0; i < 100; i++)
z.add((int) (Math.random() * 200));
BTree<Integer, Integer> bt = new BTree<Integer, Integer>(6);
System.out.println("当前树为一棵" + bt.Max + "阶B树,每个节点最多拥有" + bt.Max + "个节点,最少拥有" + bt.Min_len + "个节点");
for (int i = 0; i < 100; i++)
bt.Insert(z.get(i), i);
System.out.println("删除前初始状态");
bt.LevelOrder();
System.out.println("-----------------------------------------------\n");
for (int i = 0; i < 95; i++) {
System.out.println("第" + (i + 1) + "次删除" + z.get(i) + ": ");
bt.Remove(z.get(i));
bt.LevelOrder();
System.out.println("-----------------------------------------");
}
System.out.println(" ");
}
}