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(" ");
        }
    }
  • 相关阅读:
    spark 读取mongodb失败,报executor time out 和GC overhead limit exceeded 异常
    在zepplin 使用spark sql 查询mongodb的数据
    Unable to query from Mongodb from Zeppelin using spark
    spark 与zepplin 版本兼容
    kafka 新旧消费者的区别
    kafka 新生产者发送消息流程
    spark ui acl 不生效的问题分析
    python中if __name__ == '__main__': 的解析
    深入C++的new
    NSSplitView
  • 原文地址:https://www.cnblogs.com/INnoVationv2/p/8978383.html
Copyright © 2011-2022 走看看