B树实现

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("
");
                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("-----------------------------------------------
");
        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(" ");
    }
}
原文地址:https://www.cnblogs.com/INnoVationv2/p/8978383.html