Created
January 17, 2018 15:25
-
-
Save johannes-weber/f5806e922cc707b5d159baa4860df090 to your computer and use it in GitHub Desktop.
JavaScript implementation of a Min and Max Heap
This file contains hidden or 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
function Heap (compareFunc) { | |
var _self = this; | |
this.elements = []; | |
this.compareFunc = compareFunc; | |
_self.swap = function(aIdx, bIdx) { | |
var a = _self.elements[aIdx]; | |
var b = _self.elements[bIdx]; | |
var tmp = a; | |
_self.elements[aIdx] = b; | |
_self.elements[bIdx] = tmp; | |
if((a instanceof Object) && (b instanceof Object)) { | |
a['_index'] = bIdx; | |
b['_index'] = aIdx; | |
} | |
}; | |
_self.set = function(element, i) { | |
if ((i < 0) || i >= _self.elements.length) { | |
throw "index out of range." | |
} | |
_self.elements[i] = element; | |
if(element instanceof Object) { | |
element['_index'] = i; | |
} | |
}; | |
_self.parent = function(i) { | |
if (i == 0) { | |
return 0; | |
} | |
var idx = Math.floor((i - 1) / 2); | |
return idx; | |
}; | |
_self.leftChild = function(i) { | |
var idx = (2 * i) + 1; | |
if (_self.elements.length <= idx) { | |
return -1; | |
} | |
return idx; | |
}; | |
_self.rightChild = function(i) { | |
var idx = (2 * i) + 2; | |
if (_self.elements.length <= idx) { | |
return -1; | |
} | |
return idx; | |
}; | |
_self.upHeap = function(i) { | |
var child = _self.elements[i]; | |
var parentIdx = _self.parent(i); | |
if(parentIdx === -1) { | |
// No parent. | |
return; | |
} | |
if (i === parentIdx) { | |
return; | |
} | |
var parent = _self.elements[parentIdx]; | |
if (compareFunc(child, parent)) { | |
// Swap. | |
_self.swap(i, parentIdx); | |
_self.upHeap(parentIdx); | |
} | |
}; | |
_self.downHeap = function(i) { | |
var node = _self.elements[i]; | |
var rightChildIdx = _self.rightChild(i); | |
var leftChildIdx = _self.leftChild(i); | |
var rightChild = null; | |
var leftChild = null; | |
var minIdx = -1; | |
var min = null; | |
if ((rightChildIdx === -1) && (leftChildIdx === -1)) { | |
return | |
} | |
if (rightChildIdx !== -1) { | |
rightChild = _self.elements[rightChildIdx]; | |
minIdx = rightChildIdx; | |
min = rightChild; | |
} | |
if (leftChildIdx !== -1) { | |
leftChild = _self.elements[leftChildIdx]; | |
minIdx = leftChildIdx; | |
min = leftChild; | |
} | |
if ((rightChild !== null) && (leftChild !== null)) { | |
if(compareFunc(rightChild, leftChild)) { | |
minIdx = rightChildIdx; | |
min = rightChild; | |
} | |
else { | |
minIdx = leftChildIdx; | |
min = leftChild; | |
} | |
} | |
if (compareFunc(min, node)) { | |
// Swap. | |
_self.swap(minIdx, i); | |
_self.downHeap(minIdx); | |
} | |
}; | |
_self.heapify = function(i) { | |
if ((i < 0) || (i >= _self.elements.length)) { | |
throw "index out of range."; | |
} | |
var node = _self.elements[i]; | |
var parent = _self.elements[_self.parent(i)]; | |
if (_self.compareFunc(node, parent)) { | |
_self.upHeap(i); | |
} | |
else { | |
_self.downHeap(i); | |
} | |
}; | |
_self.Peek = function() { | |
if (_self.elements.length == 0) { | |
return null; | |
} | |
return _self.elements[0]; | |
}; | |
_self.Pop = function() { | |
if (_self.elements.length == 0) { | |
return null; | |
} | |
var result = _self.elements[0]; | |
// Place last element on root and heapify. | |
var last = _self.elements.splice(_self.elements.length-1, 1)[0]; | |
if (_self.elements.length > 0) { | |
_self.set(last, 0); | |
_self.downHeap(0); | |
} | |
return result; | |
}; | |
_self.Push = function(element) { | |
_self.elements.push(element); | |
var idx = _self.elements.length - 1; | |
if(element instanceof Object) { | |
element['_index'] = idx; | |
if('on' in element) { | |
element.on('change', function(value) { | |
_self.heapify(element['_index']); | |
}); | |
} | |
} | |
_self.upHeap(idx); | |
}; | |
}; |
This file contains hidden or 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
// max heap compare | |
var maxHeapCompareFunc = function(a, b) { return a > b; }; | |
// min heap compare function. | |
var minHeapCompareFunc = function(a, b) { return a < b; }; | |
var maxHeap = new Heap(maxHeapCompareFunc); | |
maxHeap.Push(1); | |
maxHeap.Peek(1); | |
maxHeap.Pop(1); | |
var minHeap = new Heap(maxHeapCompareFunc); | |
minHeap.Push(1); | |
minHeap.Peek(1); | |
minHeap.Pop(1); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment