I implemented the classic Sorting Algs in JS for practice. I come from a C++/Java background. Just wanted to make sure I didn't miss anything or if there was a 'better' JS way of doing it.
Also, I did notice I run into some performance issues with smaller seed values for the random generator in quick sort. I know quick sort, in general struggles with lots of duplicate keys (hence the invention of 3-way QS), so for the moment I am just attributing it to that, unless you see anything I did wrong.
//Helper functions
var swap = function(toSort, x, y) {
var temp = toSort[x];
toSort[x] = toSort[y];
toSort[y] = temp;
}
//Entry point
var masterArray = new Array();
for (var i = 0; i < 50; i++) {
masterArray.push(Math.floor(Math.random()*10000) + 1);
}
console.log(masterArray);
var toSort = masterArray.slice(0);
selection (toSort);
console.log("After selection " + toSort);
toSort = masterArray.slice(0);
insertion (toSort);
console.log("After insertion " + toSort);
toSort = masterArray.slice(0);
shell(toSort);
console.log("After shell " + toSort);
toSort = masterArray.slice(0);
mergeSort (toSort);
console.log("After merge " + toSort);
toSort = masterArray.slice(0);
quickSort (toSort);
console.log("After quick " + toSort);
toSort = masterArray.slice(0);
threeWayQuick (toSort);
console.log("After 3-way quick " + toSort);
//Basic Sorting Algorithms
var selection = function(toSort) {
for (var i = 0; i < toSort.length; i++) {
var min = i;
for (var j = i+1; j <toSort.length; j++) {
if (toSort[j] < toSort[min]) {
min = j;
}
}
swap(toSort, i, min);
}
}
var insertion = function(toSort) {
for (var i = 0; i < toSort.length; i++) {
for (j = i; j > 0; j--) {
if (toSort[j] < toSort[j-1]) {
swap(toSort, j, j-1);
} else {
break;
}
}
}
}
var shell = function(toSort) {
var h = 0;
while (h < toSort.length/3) {
h = h*3+1;
}
while (h >= 1) {
for (var i = h; i < toSort.length; i++) {
for (var j = i; j >= h; j -= h) {
if(toSort[j] < toSort[j-h]) {
swap(toSort, j, j-h);
}
}
}
h = parseInt(h/3);
}
}
var mergeSort = function(toSort) {
var sort = function(lo, hi) {
if (hi <= lo) {
return;
}
var mid = parseInt(lo + (hi - lo)/2);
sort(lo, mid);
sort(mid+1, hi);
merge(lo, mid, hi);
}
var merge = function(lo, mid, hi) {
var i = lo;
var j = mid+1;
for (var k = lo; k <= hi; k++) {
aux[k] = toSort[k];
}
for (var k = lo; k <= hi; k++) {
if (i > mid) { //If everything in the left sub array has already been merged
toSort[k] = aux[j++];
} else if (j > hi) { //If everything in the right sub array has already been merged
toSort[k] = aux[i++];
} else if (aux[j] < aux[i]) { //If the item in the right sub array is smaller
toSort[k] = aux[j++];
} else { //If the item in the left sub array is smaller
toSort[k] = aux[i++];
}
}
}
var aux = [toSort.length];
sort(0, toSort.length-1);
}
var quickSort = function (toSort) {
var partition = function (toSort, lo, hi) {
var i = lo + 1;
var j = hi;
while (true) {
while (toSort[i] < toSort[lo] && i < hi) {
i++;
}
while (toSort[j] > toSort[lo] && j > lo) {
j--;
}
if (i >= j) {
break;
}
swap(toSort, i, j);
}
swap(toSort, lo, j);
return j;
}
var sort = function (toSort, lo, hi) {
if (hi <= lo) {
return;
}
var mid = partition(toSort, lo, hi);
sort(toSort, lo, mid-1);
sort(toSort, mid+1, hi);
}
sort(toSort, 0, toSort.length-1);
}
var threeWayQuick = function(toSort) {
var sort = function(toSort, lo, hi) {
if (hi <= lo) {
return;
}
var lt = lo
var gt = hi;
var i = lo;
while (i <= gt) {
if (toSort[i] < toSort[lt]) {
swap(toSort, lt, i);
lt++;
i++;
}
else if (toSort[i] > toSort[lt]) {
swap(toSort, i, gt);
gt--;
}
else {
i++;
}
}
sort(toSort, lo, lt-1);
sort(toSort, gt+1, hi);
}
sort(toSort, 0, toSort.length-1);
}
quickSort
doesn't work, it hangs... – elclanrs Mar 17 at 1:16threeWaySort([2,3,4,1,2,1,1,1,7,5,6])
and the output wasn't all in order. – elclanrs Mar 17 at 1:20