class Heap {
constructor() {
this
.h = [];
}
parent(index) {
if
(index > 0) {
return
Math.floor((index - 1) / 2);
}
}
lchild(index) {
return
2 * index + 1;
}
rchild(index) {
return
2 * index + 2;
}
addItem(item) {
this
.h.push(item);
if
(
this
.h.length === 1) {
return
;
}
let index =
this
.h.length - 1;
let parent =
this
.parent(index);
while
(index > 0 && item <
this
.h[parent]) {
[
this
.h[index],
this
.h[parent]] = [
this
.h[parent],
this
.h[index]];
index = parent;
parent =
this
.parent(index);
}
}
deleteItem() {
const length =
this
.h.length;
[
this
.h[0],
this
.h[length - 1]] = [
this
.h[length - 1],
this
.h[0]];
const deleted =
this
.h.pop();
this
.moveDownHeapify(0);
return
deleted;
}
moveDownHeapify(index) {
const lc =
this
.lchild(index);
const rc =
this
.rchild(index);
const length =
this
.h.length;
let smallest = index;
if
(lc < length &&
this
.h[lc] <=
this
.h[smallest]) {
smallest = lc;
}
if
(rc < length &&
this
.h[rc] <=
this
.h[smallest]) {
smallest = rc;
}
if
(smallest !== index) {
[
this
.h[smallest],
this
.h[index]] = [
this
.h[index],
this
.h[smallest]];
this
.moveDownHeapify(smallest);
}
}
increaseItem(index, value) {
if
(value <=
this
.h[index]) {
return
;
}
this
.h[index] = value;
this
.moveDownHeapify(index);
}
}
class OptimalMergePattern {
constructor(n, items) {
this
.n = n;
this
.items = items;
this
.heap =
new
Heap();
}
optimalMerge() {
if
(
this
.n <= 0) {
return
0;
}
if
(
this
.n === 1) {
return
this
.items[0];
}
for
(const item of
this
.items) {
this
.heap.addItem(item);
}
let count = 0;
while
(
this
.heap.h.length !== 1) {
const tmp =
this
.heap.deleteItem();
count += tmp +
this
.heap.h[0];
this
.heap.increaseItem(0, tmp +
this
.heap.h[0])
}
return
count
}
}
let OMP =
new
OptimalMergePattern(6, [2, 3, 4, 5, 6, 7])
let ans = OMP.optimalMerge()
console.log(
"Minimum Computations ="
, ans)