Java实现B树

水平不高,数据结构小学生,java实现B树,纯原创,为了省事,每一个节点只有key,没有写value属性,周末两天在家全部时间+两个工作日的晚上,兴奋之余发布在csdn上,显摆一下,哈哈

package tree;

public class BTree {

    public static final int M = 3;
    @SuppressWarnings("unused")
    private static final int NODES_MIN_LENGTH = M % 2 == 0 ? M / 2 - 1 : M / 2;
    protected BTree parent;
    protected int count;
    protected Node[] nodes = new Node[M + 1];

    public static class Node {
        public int key = Integer.MAX_VALUE;
        public BTree child;

        public Node(int key, BTree child) {
            super();
            this.key = key;
            this.child = child;
        }

        public Node() {
            super();
        }

    }

    public static BTree initBTree() {
        BTree btree = new BTree();
        for (int i = 0; i < btree.nodes.length; i++) {
            btree.nodes[i] = new Node();
        }
        return btree;
    }

    public static class Result {
        public BTree node;
        public boolean find;
        public int position;

        public Result(BTree node, boolean find, int position) {
            super();
            this.node = node;
            this.find = find;
            this.position = position;
        }

        public Result() {
            super();
        }
    }

    public static Result nodeSearch(BTree node, int key) {
        Result result = new Result();
        result.node = node;
        int high = node.count;
        int low = 1;
        int mid = (low + high) / 2;
        while (true) {
            if (node.nodes[mid].key == key) {
                result.find = true;
                result.position = mid;
                return result;
            }
            if (node.nodes[mid].key > key) {
                high = mid;
                mid = (low + high) / 2;
            } else {
                low = mid;
                mid = (low + high) / 2;
            }
            if (mid == low) {
                if (node.nodes[mid].key == key) {
                    result.find = true;
                    result.position = mid;
                    return result;
                }
                if (low == high) {
                    if (node.nodes[mid].key < key) {
                        result.find = false;
                        result.position = mid;
                        return result;
                    } else {
                        result.find = false;
                        result.position = mid - 1;
                        return result;
                    }

                }
                if (node.nodes[mid + 1].key == key) {
                    result.find = true;
                    result.position = mid + 1;
                    return result;
                }
                if (node.nodes[mid].key < key && node.nodes[mid + 1].key > key) {
                    result.find = false;
                    result.position = mid;
                    return result;
                }
                if (node.nodes[mid + 1].key < key) {
                    result.find = false;
                    result.position = mid + 1;
                    return result;
                }
                if (key < node.nodes[mid].key) {
                    result.find = false;
                    result.position = mid - 1;
                    return result;
                }
            }
        }
    }

    public static Result search(BTree root, int key) {
        if (root.count == 0) {
            return new Result(root, false, 0);
        }
        BTree node = root;
        Result result;
        while (true) {
            result = nodeSearch(node, key);
            if (result.find)
                break;
            else {
                if (result.node.nodes[result.position].child != null) {
                    node = result.node.nodes[result.position].child;
                } else
                    break;
            }
        }
        return result;
    }

    public static int insertBTreeNode(Result result, int key) {
        for (int i = result.node.count; i > result.position; i--)
            result.node.nodes[i + 1] = result.node.nodes[i];
        result.node.nodes[result.position + 1] = new Node(key, null);
        result.node.count++;
        return result.node.count == M ? 0 : 1;
    }

    public static BTree insertBtree(BTree root, int key) {
        Result result = search(root, key);
        if (!result.find && insertBTreeNode(result, key) == 0) {
            BTree tempRoot = split(result.node);
            if (tempRoot != null)
                root = tempRoot;
        }
        return root;
    }

    private static BTree split(BTree node) {
        BTree root = null;
        while (node.count == M) {
            BTree leftNode = initBTree();
            BTree rightNode = initBTree();
            leftNode.parent = rightNode.parent = node.parent;
            int leftEnd = NODES_MIN_LENGTH;
            int middle = leftEnd + 1;
            int rightBegin = leftEnd + 2;
            leftNode.count = leftEnd;
            rightNode.count = M - rightBegin + 1;
            for (int i = 0; i <= leftEnd; i++) {
                leftNode.nodes[i] = node.nodes[i];
                if (node.nodes[i].child != null)
                    node.nodes[i].child.parent = leftNode;
            }
            for (int i = rightBegin; i <= M; i++) {
                rightNode.nodes[i - rightBegin + 1] = node.nodes[i];
                if (node.nodes[i].child != null)
                    node.nodes[i].child.parent = rightNode;
            }
            Node middleNode = node.nodes[middle];
            if (middleNode.child != null) {
                rightNode.nodes[0].child = middleNode.child;
                rightNode.nodes[0].child.parent = rightNode;
            }
            middleNode.child = rightNode;
            BTree parent = node.parent;
            if (parent != null) {
                int i = parent.count;
                while (parent.nodes[i].key > middleNode.key) {
                    parent.nodes[i + 1] = parent.nodes[i];
                    if (--i == 0)
                        break;
                }
                parent.nodes[i].child = leftNode;
                parent.nodes[i + 1] = middleNode;
                parent.nodes[i + 1].child = rightNode;
                parent.count++;
                leftNode.parent = parent;
                rightNode.parent = parent;
                node = parent;
            } else {
                root = initBTree();
                root.count = 1;
                root.nodes[0].child = leftNode;
                root.nodes[1].key = middleNode.key;
                root.nodes[1].child = rightNode;
                leftNode.parent = root;
                rightNode.parent = root;
                break;
            }
        }
        return root;
    }

    private static void deleteInTreeNode(BTree treeNode, int position) {
        for (int i = position; i < treeNode.count; i++)
            treeNode.nodes[i] = treeNode.nodes[i + 1];
        treeNode.count--;
    }

    public static void traverseBTree(BTree root) {
        if (root.nodes[0].child == null) {
            for (int i = 1; i <= root.count; i++)
                System.out.print(root.nodes[i].key + "***");
        } else {
            traverseBTree(root.nodes[0].child);
            for (int i = 1; i <= root.count; i++) {
                System.out.print(root.nodes[i].key + "***");
                traverseBTree(root.nodes[i].child);
            }
        }
    }

    public static BTree delete(BTree root, int key) {
        System.out.println(key);
        Result result = search(root, key);
        if (result.find) {
            Node node = result.node.nodes[result.position];
            BTree treeNode = node.child;
            if (treeNode != null) {
                while (treeNode.nodes[0].child != null)
                    treeNode = treeNode.nodes[0].child;
                result.node.nodes[result.position].key = treeNode.nodes[1].key;
                deleteInTreeNode(treeNode, 1);
            } else {
                treeNode = result.node;
                deleteInTreeNode(treeNode, result.position);
            }
            if (treeNode.count < NODES_MIN_LENGTH && treeNode.parent != null) {
                while (treeNode.count < NODES_MIN_LENGTH) {
                    BTree brother;
                    // CTN意为currentTreeNode
                    boolean CTNIsLast = false;
                    int CTNInParentIndex = 0;
                    for (int i = 0; i <= treeNode.parent.count; i++)
                        if (treeNode.parent.nodes[i].child.equals(treeNode)) {
                            CTNInParentIndex = i;
                            break;
                        }
                    if (CTNInParentIndex == treeNode.parent.count) {
                        CTNIsLast = true;
                        brother = treeNode.parent.nodes[CTNInParentIndex - 1].child;
                    } else {
                        brother = treeNode.parent.nodes[CTNInParentIndex + 1].child;
                    }
                    if (!CTNIsLast) {
                        treeNode.nodes[++treeNode.count].key = treeNode.parent.nodes[CTNInParentIndex + 1].key;
                        treeNode.nodes[treeNode.count].child = brother.nodes[0].child;
                        if (treeNode.nodes[treeNode.count].child != null)
                            treeNode.nodes[treeNode.count].child.parent = treeNode;
                        if (brother.count > NODES_MIN_LENGTH) {
                            treeNode.parent.nodes[CTNInParentIndex + 1].key = brother.nodes[1].key;
                            deleteInTreeNode(brother, 0);
                            brother.nodes[0].key = Integer.MAX_VALUE;
                        } else {
                            if (brother.nodes[0].child != null) {
                                for (int i = 1; i <= brother.count; i++) {
                                    treeNode.nodes[++treeNode.count] = brother.nodes[i];
                                    treeNode.nodes[treeNode.count].child.parent = treeNode;
                                }
                            } else {
                                for (int i = 1; i <= brother.count; i++)
                                    treeNode.nodes[++treeNode.count] = brother.nodes[i];
                            }
                            deleteInTreeNode(treeNode.parent, CTNInParentIndex + 1);
                        }
                    } else {
                        if (brother.count > NODES_MIN_LENGTH) {
                            for (int i = treeNode.count + 1; i >= 1; i--)
                                treeNode.nodes[i] = treeNode.nodes[i - 1];
                            treeNode.nodes[1].key = treeNode.parent.nodes[CTNInParentIndex].key;
                            treeNode.count++;
                            if (brother.nodes[brother.count].child != null) {
                                treeNode.nodes[0].child = brother.nodes[brother.count].child;
                                treeNode.nodes[0].child.parent = treeNode;
                            }
                            treeNode.parent.nodes[CTNInParentIndex].key = brother.nodes[brother.count].key;
                            deleteInTreeNode(brother, brother.count);
                        } else {
                            treeNode.nodes[0].key = treeNode.parent.nodes[CTNInParentIndex].key;
                            for (int i = treeNode.count; i >= 0; i--)
                                treeNode.nodes[i + 1 + brother.count] = treeNode.nodes[i];
                            treeNode.count += 1 + brother.count;
                            deleteInTreeNode(treeNode.parent, CTNInParentIndex);
                            treeNode.parent.nodes[CTNInParentIndex - 1].child = treeNode;
                            for (int i = 0; i <= brother.count; i++) {
                                treeNode.nodes[i] = brother.nodes[i];
                                if (treeNode.nodes[i].child != null)
                                    treeNode.nodes[i].child.parent = treeNode;
                            }
                        }
                    }
                    if (treeNode.parent == null)
                        return treeNode;
                    if (treeNode.parent.count == 0 && treeNode.parent.parent == null) {
                        treeNode.parent = null;
                        return treeNode;
                    }
                    if (treeNode.parent.count < NODES_MIN_LENGTH)
                        treeNode = treeNode.parent;
                }
            }
        }
        return root;
    }
}
    原文作者:B树
    原文地址: https://blog.csdn.net/chenzhichao/article/details/51327187
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞