Btree insert only implemented.
parent
0652e7eb43
commit
0bbf008a75
|
@ -0,0 +1,151 @@
|
|||
"use strict";
|
||||
|
||||
// const fs = require('fs');
|
||||
// const {EOL} = require('os');
|
||||
|
||||
let enable_logging = false;
|
||||
|
||||
function log(...s) {
|
||||
if (!enable_logging) {
|
||||
return;
|
||||
}
|
||||
console.log.apply(null, s);
|
||||
}
|
||||
|
||||
function make_node(k) {
|
||||
return {
|
||||
level: k,
|
||||
// temporarily allowing having one more element before split
|
||||
keys: [], // k node can have k-1 keys, they are sorted
|
||||
children: [] // k node can have k children
|
||||
};
|
||||
};
|
||||
|
||||
function binary_search(arr, el) {
|
||||
if (!arr.length) {
|
||||
log('Arr is empty');
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (el < arr[0]) {
|
||||
log(`El ${el} is smaller than ${arr[0]}`);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (el > arr[arr.length - 1]) {
|
||||
log(`El ${el} is bigger than ${arr[arr.length - 1]}`);
|
||||
return arr.length;
|
||||
}
|
||||
|
||||
let i = 0;
|
||||
let j = arr.length - 1;
|
||||
let p;
|
||||
while (i < j - 1) {
|
||||
p = (i + j) >> 1; // dividing by 2 but javascript can't do it without Math.floor
|
||||
if (arr[p] <= el) {
|
||||
i = p;
|
||||
} else {
|
||||
j = p;
|
||||
}
|
||||
}
|
||||
|
||||
return i+1;
|
||||
}
|
||||
|
||||
function btree_insert(node, el) {
|
||||
log(`Adding ${el} into`, node);
|
||||
if (!node) {
|
||||
return [null, el, null];
|
||||
}
|
||||
|
||||
const idx = binary_search(node.keys, el);
|
||||
log(`Got index ${idx}`);
|
||||
const child = node.children[idx];
|
||||
let result = btree_insert(child, el);
|
||||
if (!result) {
|
||||
log('No merging root from sub');
|
||||
return null; // we are all good
|
||||
}
|
||||
|
||||
let [left, root, right] = result;
|
||||
log(`Got new root ${root} and sub trees`, left, right);
|
||||
node.keys.splice(idx, 0, root);
|
||||
node.children[idx] = left;
|
||||
node.children.splice(idx+1, 0, right);
|
||||
|
||||
log(`Node size: ${node.keys.length}, node level: ${node.level}`);
|
||||
if (node.keys.length > node.level) {
|
||||
let h = node.level >> 1;
|
||||
log(`Splitting`);
|
||||
log(node.keys, `h index ${h}`);
|
||||
let left = make_node(node.level);
|
||||
let right = make_node(node.level);
|
||||
let root = node.keys[h];
|
||||
console.log(`Children`, node.children);
|
||||
left.keys = node.keys.slice(0, h);
|
||||
left.children = node.children.slice(0, h+1);
|
||||
right.keys = node.keys.slice(h+1);
|
||||
right.children = node.children.slice(h+1);
|
||||
log('Result', left, root, right);
|
||||
return [left, root, right];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function make_tree(t, result) {
|
||||
if (!result) {
|
||||
return t;
|
||||
}
|
||||
|
||||
let [left, el, right] = result;
|
||||
let root = make_node(t.level);
|
||||
root.keys[0] = el;
|
||||
root.children[0] = left;
|
||||
root.children[1] = right;
|
||||
return root;
|
||||
}
|
||||
|
||||
function display_tree(t, path = '') {
|
||||
if (!t) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < t.keys.length; i++) {
|
||||
display_tree(t.children[i], path + "/" + i);
|
||||
console.log(path + " " + t.keys[i]);
|
||||
}
|
||||
display_tree(t.children[t.keys.length], path + "/" + t.keys.length);
|
||||
}
|
||||
|
||||
// let arr = [1, 3, 5, 7];
|
||||
|
||||
// const el = -2;
|
||||
// const pos = binary_search(arr, el);
|
||||
// arr.splice(pos, 0, el);
|
||||
// log(`Binary search`, arr);
|
||||
|
||||
let t = make_node(2);
|
||||
// t = make_tree(t, btree_insert(t, 1));
|
||||
// t = make_tree(t, btree_insert(t, 2));
|
||||
// t = make_tree(t, btree_insert(t, 3));
|
||||
// t = make_tree(t, btree_insert(t, 4));
|
||||
// t = make_tree(t, btree_insert(t, 5));
|
||||
// t = make_tree(t, btree_insert(t, 6));
|
||||
// t = make_tree(t, btree_insert(t, 7));
|
||||
|
||||
display_tree(t);
|
||||
// enable_logging = true;
|
||||
t = make_tree(t, btree_insert(t, 1));
|
||||
t = make_tree(t, btree_insert(t, 2));
|
||||
t = make_tree(t, btree_insert(t, 3));
|
||||
t = make_tree(t, btree_insert(t, 4));
|
||||
t = make_tree(t, btree_insert(t, 5));
|
||||
t = make_tree(t, btree_insert(t, 6));
|
||||
t = make_tree(t, btree_insert(t, 7));
|
||||
t = make_tree(t, btree_insert(t, 8));
|
||||
t = make_tree(t, btree_insert(t, 5));
|
||||
t = make_tree(t, btree_insert(t, 5));
|
||||
// console.log(t);
|
||||
//enable_logging = false;
|
||||
display_tree(t);
|
Loading…
Reference in New Issue