Skip to content

Instantly share code, notes, and snippets.

@ambud
Last active September 7, 2017 23:37
Show Gist options
  • Save ambud/57dc6d8879c260f7b1028f9e4f80dc8f to your computer and use it in GitHub Desktop.
Save ambud/57dc6d8879c260f7b1028f9e4f80dc8f to your computer and use it in GitHub Desktop.
Btree Implementation
/**
* Copyright 2017 Ambud Sharma
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package btree.btree;
import java.util.Arrays;
/**
* Btree Implementation
*/
@SuppressWarnings("unused")
public class Btree {
private Node root;
public void insert(int key) {
Node insert = insert(key, root);
if (insert != null) {
root = insert;
}
}
public Node insert(int key, Node node) {
int i = 0;
for (; i < node.count; i++) {
if (key < node.keys[i]) {
break;
}
}
if (node.isLeaf) {
for (int k = node.keys.length - 1; k > i; k--) {
node.keys[k] = node.keys[k - 1];
}
node.count++;
node.keys[i] = key;
} else {
Node node2 = node.children[i];
if (node2 == null) {
node2 = new Node();
}
Node insert = insert(key, node2);
if (insert != null) {
for (int k = node.keys.length - 1; k > i; k--) {
node.keys[k] = node.keys[k - 1];
node.children[k + 1] = node.children[k];
}
node.count++;
node.keys[i] = insert.keys[0];
node.children[i] = insert.children[0];
node.children[i + 1] = insert.children[1];
}
}
if (node.count == node.keys.length) {
return split(node);
}
return null;
}
public static Node split(Node node) {
int splitpoint = node.count / 2;
int splitKey = node.keys[splitpoint];
Node nn = new Node();
for (int i = splitpoint + 1, j = 0; i < node.keys.length; i++, j++) {
nn.keys[j] = node.keys[i];
node.keys[i] = 0;
}
node.keys[splitpoint] = 0;
if (!node.isLeaf) {
nn.isLeaf = false;
for (int i = splitpoint + 1, j = 0; i < node.children.length; i++, j++) {
nn.children[j] = node.children[i];
node.children[i] = null;
}
} else {
nn.isLeaf = true;
}
nn.count = splitpoint;
node.count = splitpoint;
Node parent = new Node();
parent.isLeaf = false;
parent.keys[0] = splitKey;
parent.count++;
parent.children[0] = node;
parent.children[1] = nn;
return parent;
}
public boolean findNode(int key) {
Node result = findNode(key, root);
return result != null;
}
public Node findNode(int key, Node node) {
if (node.isLeaf) {
for (int i = 0; i < node.count; i++) {
if (node.keys[i] == key) {
return node;
}
}
return null;
} else {
int i = 0;
for (; i < node.count; i++) {
if (key < node.keys[i]) {
break;
} else if (key == node.keys[i]) {
return node;
}
}
return findNode(key, node.children[i]);
}
}
public static void main(String[] args) {
testInserts();
// testSearch();
// testSplits();
}
private static void testInserts() {
Btree tree = new Btree();
tree.root = new Node();
tree.root.isLeaf = true;
tree.insert(5);
tree.insert(2);
tree.insert(4);
tree.insert(10);
tree.insert(1);
tree.insert(11);
tree.insert(15);
tree.insert(7);
tree.insert(9);
tree.insert(12);
tree.insert(3);
tree.insert(8);
System.out.println("\nRoot:" + tree.root);
System.out.println("\nRoot keys:" + Arrays.toString(tree.root.keys));
for (int i = 0; i < 20; i++) {
System.out.println(tree.findNode(i) + "\t" + i);
}
}
private static void testSplits() {
Node node = new Node();
node.isLeaf = false;
node.keys[0] = 4;
node.keys[1] = 8;
node.keys[2] = 13;
node.count = 3;
node.children[0] = new Node();
node.children[0].isLeaf = true;
node.children[0].keys[0] = 0;
node.children[0].keys[1] = 1;
node.children[0].keys[2] = 2;
node.children[0].count = 3;
node.children[1] = new Node();
node.children[1].isLeaf = true;
node.children[1].keys[0] = 5;
node.children[1].keys[1] = 6;
node.children[1].keys[2] = 7;
node.children[1].count = 3;
node.children[2] = new Node();
node.children[2].isLeaf = true;
node.children[2].keys[0] = 10;
node.children[2].keys[1] = 11;
node.children[2].keys[2] = 12;
node.children[2].count = 3;
node.children[3] = new Node();
node.children[3].isLeaf = true;
node.children[3].keys[0] = 15;
node.children[3].keys[1] = 16;
node.children[3].keys[2] = 17;
node.children[3].count = 3;
Node split = split(node);
System.out.println(split);
split = new Node();
split.isLeaf = true;
split.keys[0] = 15;
split.keys[1] = 16;
split.keys[2] = 17;
split.count = 3;
System.out.println(split(split));
}
public static void testSearch() {
Btree tree = new Btree();
tree.root = new Node();
tree.root.keys[0] = 3;
tree.root.keys[1] = 6;
tree.root.count = 2;
tree.root.children[0] = new Node();
tree.root.children[0].isLeaf = true;
tree.root.children[0].count = 3;
tree.root.children[0].keys[0] = 0;
tree.root.children[0].keys[1] = 1;
tree.root.children[0].keys[2] = 2;
tree.root.children[1] = new Node();
tree.root.children[1].isLeaf = true;
tree.root.children[1].count = 2;
tree.root.children[1].keys[0] = 4;
tree.root.children[1].keys[1] = 5;
tree.root.children[2] = new Node();
tree.root.children[2].isLeaf = true;
tree.root.children[2].count = 2;
tree.root.children[2].keys[0] = 7;
tree.root.children[2].keys[1] = 9;
System.out.println("1:" + tree.findNode(1, tree.root));
System.out.println("3:" + tree.findNode(3, tree.root));
System.out.println("5:" + tree.findNode(5, tree.root));
System.out.println("8:" + tree.findNode(8, tree.root));
System.out.println("9:" + tree.findNode(9, tree.root));
}
public static class Node {
static final int MAX = 8;
int count;
int[] keys = new int[MAX - 1];
boolean isLeaf;
Node[] children = new Node[MAX];
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "\nNode [count=" + count + ", keys=" + Arrays.toString(keys) + ", isLeaf=" + isLeaf + ""
+ ((!isLeaf) ? ", children=" + Arrays.toString(children) : "") + "]";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment