Skip to content

Instantly share code, notes, and snippets.

@maninak
Created July 7, 2017 18:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save maninak/512ea415b0fd64ec41d852dbd4188e5c to your computer and use it in GitHub Desktop.
Save maninak/512ea415b0fd64ec41d852dbd4188e5c to your computer and use it in GitHub Desktop.
A javascript implementation of Heap Sort algorithm that sorts an array of objects {age: number, string: name} in ascending order of age.
/* ------ Input Data ---------------------------*/
let people = [
{
"age": 34,
"name": "Malone Warren"
},
{
"age": 50,
"name": "James Lane"
},
{
"age": 30,
"name": "Vivian Sims"
},
{
"age": 26,
"name": "Doreen Giles"
},
{
"age": 24,
"name": "Irma Pennington"
},
{
"age": 46,
"name": "Bell Savage"
},
{
"age": 56,
"name": "Nanette Chaney"
},
{
"age": 37,
"name": "Faye Porter"
},
{
"age": 54,
"name": "Blanche Sharpe"
},
{
"age": 54,
"name": "Schneider Parker"
},
{
"age": 38,
"name": "Arnold Fletcher"
},
{
"age": 48,
"name": "Laurie Calhoun"
},
{
"age": 48,
"name": "Leann Poole"
},
{
"age": 33,
"name": "Branch Guerrero"
},
{
"age": 19,
"name": "Susana Walters"
},
{
"age": 42,
"name": "Maricela Bauer"
},
{
"age": 43,
"name": "Graciela Sweeney"
},
{
"age": 62,
"name": "Dudley Espinoza"
},
{
"age": 24,
"name": "Amy Valencia"
},
{
"age": 42,
"name": "Vega Cross"
}
];
/* ------ Heap Sort ---------------------------*/
console.log(heapSort(people));
/**
* Sort an array of people in ascending age.
*
* Heap Sort is a comparison-based sorting algorithm and can be thought of as
* an improved Selection Sort: like that algorithm, it divides its input into
* a sorted and an unsorted region, and it iteratively shrinks the unsorted
* region by extracting the largest element and moving that to the sorted region.
*
* The improvement consists of the use of a heap data structure rather than a
* linear-time search to find the maximum. Although somewhat slower in practice
* on most machines than a well-implemented quicksort, it has the advantage
* of a more favorable worst-case time complaxity O(n log n) and a memory
* complexity of just 0(1).
*
* Heapsort is an in-place algorithm, but it is not a stable sort.
* @param {Array[Object{age: number, name: string}]} people - an array of people objects
* @returns the provided array, with its objects sorted in ascending age
*/
function heapSort(people) {
heapify(people, people.length);
// Starting from the last leaves of the heap towards the root,
// swap it with the first element (optimisation),
// and proceed to make the subtree of heap format
for (let i = people.length - 1; i > 0; i--) {
swap(people, i, 0);
max_heapify(people, 0, i);
}
return people;
}
/**
* Makes the initial pass of heapifying the array.
* @param {[{age: number, name: string}]} people - an array of people objects
* @param {number} length - count of objects within the people array
*/
function heapify(people, length) {
// i is the index of the heap root
for (let i = Math.floor(length/2); i >= 0; i--) {
max_heapify(people, i, length);
}
}
/**
* Brings the tree to a maximum heap format, with the biggest value at the root.
* @param {[{age: number, name: string}]} people - an array of people objects
* @param {number} i - index of array from where to begin
* @param {number} length - maximum index of the array up to which to check
*/
function max_heapify(people, i, length) {
let largest = i;
let leftChild, rightChild;
while (true) {
leftChild = (2 * i) + 1;
rightChild = (2 * i) + 2;
// Whichever of the leftChild or rightChild object has larger age value,
// and also has value larger than the current index,
// then mark that one as largest and then swap it with the current index.
if (leftChild < length && people[leftChild].age > people[largest].age) {
largest = leftChild;
}
if (rightChild < length && people[rightChild].age > people[largest].age) {
largest = rightChild;
}
if (i == largest) {
break;
}
swap(people, i, largest);
// We know that the just swapped object at index i is now the largest
i = largest;
}
}
/**
* Swaps the position of two objects in an array.
* @param {[]} array - the aray containing the object to be swapped
* @param {number} i - index of first object within array
* @param {number} j - index of second object within array
*/
function swap(array, i, j) {
let tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment