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(" "); } }