Created
July 7, 2017 18:49
-
-
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.
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
/* ------ 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