Adding binomial heap implementation.
parent
51aa461729
commit
0652e7eb43
|
@ -0,0 +1,153 @@
|
|||
"use strict";
|
||||
|
||||
// const fs = require('fs');
|
||||
// const {EOL} = require('os');
|
||||
|
||||
function log(s) {
|
||||
// console.log(s);
|
||||
}
|
||||
|
||||
function find_min(l) {
|
||||
if (!l || !l.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let min = l[0];
|
||||
let idx = 0;
|
||||
for (let i = 1; i < l.length; i++) {
|
||||
if (min.value > l[i].value) {
|
||||
min = l[i];
|
||||
idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
return [min, idx];
|
||||
}
|
||||
|
||||
function merge_some_level_trees(l, r) {
|
||||
// merge it into level+1 and it becomes t
|
||||
if (l.value < r.value) {
|
||||
// l becomes root
|
||||
l.children.push(r);
|
||||
l.level++;
|
||||
return l;
|
||||
} else {
|
||||
// r becomes root
|
||||
r.children.push(l);
|
||||
r.level++;
|
||||
return r;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function heap_insert(nodes, el) {
|
||||
log('Heap insert nodes: ', nodes, ', element: ', el);
|
||||
return merge_tree_lists(nodes, [{
|
||||
value: el,
|
||||
level: 0,
|
||||
children: []
|
||||
}]);
|
||||
}
|
||||
|
||||
function merge_tree_lists(l, r) {
|
||||
log('Merging tree lists l: ', l, ', r: ', r);
|
||||
if (!l) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!r) {
|
||||
return l;
|
||||
}
|
||||
|
||||
let x = [];
|
||||
|
||||
// assuming both l and r are correct fibonacci heaps so max 2 trees with the same level
|
||||
let idx = 0;
|
||||
while (l.length && r.length) {
|
||||
log(`${idx}. loop iteration`);
|
||||
if (l[0].level < r[0].level) {
|
||||
log('Case 1 l level is smaller than r level. Adding l[0]');
|
||||
x.push(l.shift());
|
||||
} else if (l[0].level > r[0].level) {
|
||||
log('Case 2 l level is bigger than r level. Adding r[0]');
|
||||
x.push(r.shift());
|
||||
} else {
|
||||
// l[0].level === r[0].level
|
||||
log('Case 3 l is the same as r level. Adding both');
|
||||
x.push(l.shift());
|
||||
x.push(r.shift());
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
log(`End of loop after ${idx} iterations`);
|
||||
log('l: ', l, ', r: ', r);
|
||||
if (l.length) {
|
||||
x = x.concat(l);
|
||||
} else if (r.length) {
|
||||
x = x.concat(r);
|
||||
}
|
||||
|
||||
log('x: ', x);
|
||||
|
||||
// the situation is we have sorted by level (ascending) with max 2 neighbouring
|
||||
// trees with the same level
|
||||
|
||||
let res = [];
|
||||
let t1, t2, t;
|
||||
while (x.length > 1) {
|
||||
if (x[0].level < x[1].level) {
|
||||
res.push(x.shift());
|
||||
} else {
|
||||
// with the same level
|
||||
t1 = x.shift();
|
||||
t2 = x.shift();
|
||||
x.unshift(merge_some_level_trees(t1, t2));
|
||||
}
|
||||
}
|
||||
|
||||
// case 0 or 1
|
||||
|
||||
while (x.length) {
|
||||
res.push(x.shift());
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
function delete_heap_min(nodes) {
|
||||
log(`Delete heap min l ${nodes.length}`);
|
||||
let [node, idx] = find_min(nodes);
|
||||
nodes.splice(idx, 1);
|
||||
return merge_tree_lists(nodes, node.children);
|
||||
}
|
||||
|
||||
let heap = [];
|
||||
// heap = heap_insert(heap, -2);
|
||||
heap = heap_insert(heap, 2);
|
||||
// heap = heap_insert(heap, -3);
|
||||
heap = heap_insert(heap, 3);
|
||||
// heap = heap_insert(heap, -1);
|
||||
heap = heap_insert(heap, -10);
|
||||
// heap = heap_insert(heap, 20);
|
||||
heap = heap_insert(heap, 100);
|
||||
|
||||
heap = heap_insert(heap, 3);
|
||||
heap = heap_insert(heap, 2);
|
||||
heap = heap_insert(heap, 1);
|
||||
heap = heap_insert(heap, -100);
|
||||
heap = heap_insert(heap, -1);
|
||||
heap = heap_insert(heap, -4);
|
||||
heap = heap_insert(heap, 4);
|
||||
heap = heap_insert(heap, 5);
|
||||
heap = heap_insert(heap, 6);
|
||||
|
||||
console.log(`Forrest of binomial trees ${heap.length}`);
|
||||
for (let el of heap) {
|
||||
console.log(`${el.value} ${el.level}`);
|
||||
}
|
||||
|
||||
while (heap.length) {
|
||||
let [node, idx] = find_min(heap);
|
||||
console.log(`Node ${node.value}, idx: ${idx}`);
|
||||
heap = delete_heap_min(heap);
|
||||
}
|
Loading…
Reference in New Issue