zoukankan      html  css  js  c++  java
  • 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(" ");
        }
    }
  • 相关阅读:
    各种小例子
    作业 5/20
    课程总结
    构建之法 读书笔记一
    Android实现本地音频播放(可拖动条)
    自我介绍
    上周总结
    《梦断代码》读书笔记三
    《梦断代码》读书笔记二
    《梦断代码》读书笔记一
  • 原文地址:https://www.cnblogs.com/INnoVationv2/p/8978383.html
Copyright © 2011-2022 走看看