Skip to content

Instantly share code, notes, and snippets.

@danielpowell4
Last active October 21, 2016 06:48
Show Gist options
  • Save danielpowell4/9a185cc9e8faac955b11a36e48dbd0c5 to your computer and use it in GitHub Desktop.
Save danielpowell4/9a185cc9e8faac955b11a36e48dbd0c5 to your computer and use it in GitHub Desktop.
Merge sort algorithm in javascript with mini-test suite. Breaks into pieces and then merges back together. Uncomment inner console logs to see it in action.
/* mergeSort
*
* basic idea is as follows:
* break an array of integrers into pieces recursively
* and merges it back together using its sorted pieces
*
* this implementation uses "take from the front put in
* the back" logic while merging
*
* find diagram at http://quiz.geeksforgeeks.org/merge-sort/
*
* uncomment console logs to watch it work!
*/
const mergeSort = (array) => {
if (array.length === 1){
return array;
}
const mid = Math.ceil((array.length/2));
// console.log('array:');
// console.log(array);
// console.log("mid:");
// console.log(mid);
const left = array.slice(0, mid);
const right = array.slice(mid);
// console.log("left:");
// console.log(left);
// console.log("right:");
// console.log(right);
const left_sorted = mergeSort(left);
const right_sorted = mergeSort(right);
// console.log('left_sorted:');
// console.log(left_sorted);
// console.log('right_sorted:');
// console.log(right_sorted);
let new_array = [];
while ( left_sorted.length && right_sorted.length ) {
// console.log('left_sorted && right_sorted')
// console.log(new_array);
new_array.push( left_sorted[0] <= right_sorted[0] ? left_sorted.shift() : right_sorted.shift() );
// console.log(new_array);
}
while (left_sorted.length) {
new_array.push(left_sorted.shift());
// console.log('left_sorted only');
// console.log(new_array);
}
while (right_sorted.length) {
new_array.push(right_sorted.shift());
// console.log('right_sorted only');
// console.log(new_array);
}
// console.log('new sorted array:');
// console.log(new_array);
return new_array;
}
// -- Test "suite"
// tallies
let pass = 0;
let fail = 0;
// adds equals function to array
// from http://stackoverflow.com/questions/7837456/how-to-compare-arrays-in-javascript
Array.prototype.equals = function (array) {
// if the other array is a falsy value, return
if (!array)
return false;
// compare lengths - can save a lot of time
if (this.length != array.length)
return false;
for (var i = 0, l=this.length; i < l; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].equals(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
};
// basic test function for newString
const test = (name, str, expected) => {
console.log(' testing ' + name);
let sortedArray = mergeSort(str);
if ( sortedArray.equals(expected) ){
pass++;
console.log(' - pass! 🐳\n');
} else {
fail++;
console.log(' - fail! 🐞 got ' + sortedArray + ' expected ' + expected + '\n');
}
};
// test runner
console.log('\nStarting Test Suite for mergeSort.js \n');
test('presorted array even length', [1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6]);
test('presorted array odd length', [1, 2, 3, 4, 5], [1, 2, 3, 4, 5]);
test('reversed array', [5, 4, 3, 2, 1], [1, 2, 3, 4, 5]);
test('symmetrically opposite', [8, 6, 4, 7, 5, 3], [3, 4, 5, 6, 7, 8]);
test('seemingly random', [123, 2, 4, 234, 7, 52, 6, 12, 22, 51], [2, 4, 6, 7, 12, 22, 51, 52, 123, 234]);
console.log('\nResults are in:');
console.log(' ' + pass + ' Wins, ' + fail + ' Loses'); // print tallies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment