algs4js
Version:
Basic algorithms and data structures implemented with es6
154 lines (131 loc) • 4.25 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* Class HeapSort
*
* Classic implementation of using a max heap to sort an array
*/
var HeapSort = function () {
function HeapSort() {
_classCallCheck(this, HeapSort);
}
_createClass(HeapSort, null, [{
key: "sort",
/**
* Perform heap sort in-place on an array
*
* @param {object} arr - the array to be sorted
*/
value: function sort(arr) {
// Build max heap so max item is at top (index zero)
this.buildHeap(arr);
// Swap max value at top for last item. Tickle down top value to N-1 heap.
for (var size = arr.length - 1; size > 0; size--) {
this.swap(arr, 0, size);
this.trickleDown(arr, size, 0);
}
}
/**
* Build a max-heap
*
* @param {object} arr - the array to be put into max heap form
*/
}, {
key: "buildHeap",
value: function buildHeap(arr) {
var firstNonLeaf = this.parent(arr.length - 1);
for (var i = firstNonLeaf; i >= 0; i--) {
this.trickleDown(arr, arr.length, i);
}
}
/**
* Trickle a node value down to its proper place in a max-heap
*
* @param {object} arr - the in-place array being sorted
* @param {number} size - the number of items in the (sub)heap being trickleDown
* @param {number} i - the parent node start point for the trickle down.
*/
}, {
key: "trickleDown",
value: function trickleDown(arr, size, i) {
var parent = i;
while (parent < size) {
var left = this.left(parent);
var right = this.right(parent);
var largest = parent;
if (left < size && arr[left] > arr[parent]) {
largest = left;
}
if (right < size && arr[right] > arr[largest]) {
largest = right;
}
if (largest !== parent) {
this.swap(arr, parent, largest);
parent = largest;
} else {
return;
}
}
}
/* eslint no-param-reassign: 0 */
/**
* Simple array swap function
*
* @param {object} arr - the array whose elements will be swapped
* @param {number} i - An index value whose value will be swapped
* @param {number} j - Another index value whose value will be swapped
*/
}, {
key: "swap",
value: function swap(arr, i, j) {
var tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
/**
* Returns the index of the parent for a child node
*
* @param {number} i - the child node index
* @return {number} the index of the parent
*/
}, {
key: "parent",
value: function parent(i) {
return Math.floor((i - 1) / 2);
}
/**
* Returns the index of the left child for a parent node
*
* @param {number} i - the parent node index
* @return {number} the index of the left child
*/
}, {
key: "left",
value: function left(i) {
return 2 * i + 1;
}
/**
* Returns the index of the parent for a node
*
* @param {number} i - the parent node index
* @return {number} the index of the right child node
*/
}, {
key: "right",
value: function right(i) {
return 2 * i + 2;
}
}]);
return HeapSort;
}();
/* Debug code
const arr = [3, 1, 5, 2, 4, 5, 6, 23];
console.log(`Before heapSort, arr: ${arr}`);
HeapSort.heapSort(arr);
console.log(`After heapSort, arr: ${arr}`);
*/
exports.default = HeapSort;
;