Last active
April 28, 2020 08:51
-
-
Save sebastianfdez/09e07df13ba35e33a671472f01d21276 to your computer and use it in GitHub Desktop.
BTree with insertion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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