Skip to content

Instantly share code, notes, and snippets.

@sebastianfdez
Last active April 28, 2020 08:51
Show Gist options
  • Save sebastianfdez/09e07df13ba35e33a671472f01d21276 to your computer and use it in GitHub Desktop.
Save sebastianfdez/09e07df13ba35e33a671472f01d21276 to your computer and use it in GitHub Desktop.
BTree with insertion
/**
* btree namespace.
* @type {BTree}
*/
export default class BTree {
constructor(order) {
/** @type {number} */
this.order = order;
/**
* Root node of the tree.
* @type {BTreeNode}
*/
this.root;
}
/**
* Insert a new value in the tree O(log N)
* @param {number} value
*/
insert(value) {
const actual = this.root;
if (actual.n === 2 * this.order - 1) {
// Create a new node to become the root
// Append the old root to the new one
const temp = new BTreeNode(false);
temp.tree = this;
this.root = temp;
temp.addChild(actual, 0);
this.split(actual, temp, 1);
this.insertNonFull(temp, parseInt(value));
} else {
this.insertNonFull(actual, parseInt(value));
}
};
/**
* Divide child node from parent into parent.values[pos-1] and parent.values[pos]
* O(1)
* @param {BTreeNode} child
* @param {BTreeNode} parent
* @param {number} pos
*/
split(child, parent, pos) {
const newChild = new BTreeNode(child.leaf);
newChild.tree = this.root.tree;
// Create a new child
// Pass values from the old child to the new
for (let k = 1; k < this.order; k++) {
newChild.addValue(child.removeValue(this.order));
}
// Trasspass child nodes from the old child to the new
if (!child.leaf) {
for (let k = 1; k <= this.order; k++) {
newChild.addChild(child.deleteChild(this.order), k - 1);
}
}
// Add new child to the parent
parent.addChild(newChild, pos);
// Pass value to parent
parent.addValue(child.removeValue(this.order - 1));
parent.leaf = false;
}
/**
* Insert a value in a not-full node. O(1)
* @param {BTreeNode} node
* @param {number} value
*/
insertNonFull(node, value) {
if (node.leaf) {
node.addValue(value);
return;
}
let temp = node.n;
while (temp >= 1 && value < node.values[temp - 1]) {
temp = temp - 1;
}
if (node.children[temp].n === 2 * this.order - 1) {
this.split(node.children[temp], node, temp + 1);
if (value > node.values[temp]) {
temp = temp + 1;
}
}
this.insertNonFull(node.children[temp], value);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment