Moved UI actions in UI object (rather than base level.

master
ben-burlingham 10 years ago
parent b61ea47464
commit 35303a9bc9
  1. 64
      index.html
  2. 130
      js/bubblesort.js
  3. 110
      js/insertionsort.js
  4. 170
      js/mergesort.js
  5. 173
      js/quicksort.js
  6. 125
      js/selectionsort.js
  7. 110
      js/shellsort.js
  8. 5
      js/visualizer.js

@ -18,8 +18,11 @@
<br>
<h2>Quicksort discussion</h2>
<p>
used by chrome.<br>
source code link
</p>
<p>used by chrome.</p>
<div class="sorter"
data-algorithm='quick'
data-stable='Maybe'
@ -30,10 +33,13 @@
data-worst-memory='0 (in place)'
></div>
<h2>Mergesort discussion</h2>
<p>used by firefox and safari. </p>
helpful: http://stackoverflow.com/questions/2967153/space-requirements-of-a-merge-sort<br>
<p>
used by firefox and safari.<br>
helpful: http://stackoverflow.com/questions/2967153/space-requirements-of-a-merge-sort<br>
source code link
</p>
<div class="sorter"
data-algorithm='merge'
data-stable='Maybe'
@ -44,37 +50,49 @@
data-worst-memory='0 (in place)'
></div>
<h2>Selection sort discussion</h2>
<p>
http://stackoverflow.com/questions/15799034/insertion-sort-vs-selection-sort <br>
finds upstram minimum and swaps with current.<br>
source code link
</p>
<h2>Shellsort discussion</h2>
several ways to pick gap width, but dependence on input data makes gap selection trivial. <br>
<div class="sorter"
data-algorithm='shell'
data-algorithm='selection'
data-stable='Maybe'
data-adaptive='Maybe'
data-worst-perf='O(n + m + 3k)'
data-avg-perf='O(n + m + 3k)'
data-best-perf='O(n + m + 3k)'
data-worst-memory='0 (in place)'
></div>
data-worst-memory='0 (in place)'>
</div>
<h2>Insertion sort discussion</h2>
<p>
how is this different from bubble and selection. <br>
swap. highlight. fade.<br>
source code link
</p>
<h2>Selection sort discussion</h2>
http://stackoverflow.com/questions/15799034/insertion-sort-vs-selection-sort <br>
finds upstram minimum and swaps with current.
<div class="sorter"
data-algorithm='selection'
data-algorithm='insertion'
data-stable='Maybe'
data-adaptive='Maybe'
data-worst-perf='O(n + m + 3k)'
data-avg-perf='O(n + m + 3k)'
data-best-perf='O(n + m + 3k)'
data-worst-memory='0 (in place)'>
</div>
data-worst-memory='0 (in place)'
></div>
<h2>Shellsort discussion</h2>
<p>
several ways to pick gap width, but dependence on input data makes gap selection trivial.<br>
Insertion sort with gap of 1.<br>
source code link
</p>
<h2>Insertion sort discussion</h2>
how is this different from bubble and selection. <br>
swap. highlight. fade.
<div class="sorter"
data-algorithm='insertion'
data-algorithm='shell'
data-stable='Maybe'
data-adaptive='Maybe'
data-worst-perf='O(n + m + 3k)'
@ -85,8 +103,12 @@
<h2>Bubble sort discussion</h2>
how is this different from insertion and selection sorts. <br>
talk about turtles and rabbits, because search loops from beginning each time. Every number out of place means a new pass must be done.
<p>
how is this different from insertion and selection sorts. <br>
talk about turtles and rabbits, because search loops from beginning each time. Every number out of place means a new pass must be done.<br>
source code link
</p>
<div class="sorter"
data-algorithm='bubble'
data-stable='Maybe'

@ -2,65 +2,67 @@
*
*/
var BubbleSort = function() {
//===== Action management.
//
this.preSort = function(arr) {
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 3, ``)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, `Starting sort.`)
};
//
this.midSort = function(arr, i) {
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.background, 1, 0, i, i, Visualizer.bg1)
.instruct(Itemgroup.background, 1, 0, (i - 1), (i - 1), Visualizer.bg1)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 3, `Comparing ${arr[i - 1]} and ${arr[i]}.`)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, ``)
};
//
this.swap = function(arr, i) {
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.background, 1, 0, i, i, Visualizer.bg1)
.instruct(Itemgroup.background, 1, 0, (i - 1), (i - 1), Visualizer.bg1)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 4, `${arr[i]} > ${arr[i - 1]}`)
.instruct(Itemgroup.message, 0, 0, 5, `Swap current and previous.`)
.instruct(Itemgroup.swap, 1, 300, i, i - 1)
};
//
this.foundSwapped = function(arr) {
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 3, ``)
.instruct(Itemgroup.message, 0, 0, 4, `Swapped elements found.`)
.instruct(Itemgroup.message, 0, 100, 5, `Recursing.`)
};
//
this.postSort = function(arr) {
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 3, ``)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, `Sorting complete.`)
var _this = this;
this.ui = {
presort: function presort(arr) {
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${_this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${_this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 3, ``)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, `Starting sort.`)
},
//
midsort: function midsort(arr, i) {
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.background, 1, 0, i, i, Visualizer.bg1)
.instruct(Itemgroup.background, 1, 0, (i - 1), (i - 1), Visualizer.bg1)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${_this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 3, `Comparing ${arr[i - 1]} and ${arr[i]}.`)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, ``)
},
//
swap: function swap(arr, i) {
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.background, 1, 0, i, i, Visualizer.bg1)
.instruct(Itemgroup.background, 1, 0, (i - 1), (i - 1), Visualizer.bg1)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${_this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 4, `${arr[i]} > ${arr[i - 1]}`)
.instruct(Itemgroup.message, 0, 0, 5, `Swap current and previous.`)
.instruct(Itemgroup.swap, 1, 300, i, i - 1)
},
//
foundSwapped: function foundSwapped(arr) {
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 3, ``)
.instruct(Itemgroup.message, 0, 0, 4, `Swapped elements found.`)
.instruct(Itemgroup.message, 0, 100, 5, `Recursing.`)
},
//
postsort: function postsort(arr) {
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${_this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${_this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 3, ``)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, `Sorting complete.`)
},
};
};
@ -101,11 +103,11 @@ BubbleSort.prototype.sort = function(arr) {
var swapped = false;
var len = arr.length;
this.preSort(arr);
this.ui.presort(arr);
for (i = 1; i < len; i++) {
this.comparisons++;
this.midSort(arr, i);
this.ui.midsort(arr, i);
if (arr[i - 1] > arr[i]) {
this.swaps++;
@ -116,16 +118,16 @@ BubbleSort.prototype.sort = function(arr) {
swapped = true;
this.swap(arr, i, i - 1);
this.ui.swap(arr, i, i - 1);
}
}
if (swapped === true) {
this.foundSwapped(arr);
this.ui.foundSwapped(arr);
this.sort(arr);
}
this.postSort(arr);
this.ui.postsort(arr);
return arr;
};

@ -2,56 +2,58 @@
*
*/
var InsertionSort = function() {
//===== Action management.
//
this.preSort = function(arr) {
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 3, ``)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, `Starting sort.`)
};
//
this.midSort = function(arr, i, j) {
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.background, 1, 0, j, j, Visualizer.bg1)
.instruct(Itemgroup.background, 1, 0, (j - 1), (j - 1), Visualizer.bg1)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 4, `Comparing [${j - 1}] and [${j}]`)
.instruct(Itemgroup.message, 0, 100, 5, ``)
};
//
this.swap = function(arr, j) {
this
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 5, `${arr[j]} < ${arr[j - 1]}, swapped.`)
.instruct(Itemgroup.swap, 1, 300, j - 1, j)
if (j - 1 > 0) {
this.instruct(Itemgroup.message, 0, 0, 3, `Continuing downstream...`)
}
else {
this.instruct(Itemgroup.message, 0, 0, 3, ``)
}
};
//
this.postSort = function(arr) {
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 3, ``)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, `Sorting complete.`)
var _this = this;
this.ui = {
presort: function presort(arr) {
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${_this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${_this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 3, ``)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, `Starting sort.`)
},
//
midsort: function midsort(arr, i, j) {
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.background, 1, 0, j, j, Visualizer.bg1)
.instruct(Itemgroup.background, 1, 0, (j - 1), (j - 1), Visualizer.bg1)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${_this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 4, `Comparing [${j - 1}] and [${j}]`)
.instruct(Itemgroup.message, 0, 100, 5, ``)
},
//
swap: function swap(arr, j) {
_this
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${_this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 5, `${arr[j]} < ${arr[j - 1]}, swapped.`)
.instruct(Itemgroup.swap, 1, 300, j - 1, j)
if (j - 1 > 0) {
_this.instruct(Itemgroup.message, 0, 0, 3, `Continuing downstream...`)
}
else {
_this.instruct(Itemgroup.message, 0, 0, 3, ``)
}
},
//
postsort: function postsort(arr) {
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${_this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${_this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 3, ``)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, `Sorting complete.`)
},
};
};
@ -93,12 +95,12 @@ InsertionSort.prototype.sort = function(arr) {
var j;
var tmp;
this.preSort(arr);
this.ui.presort(arr);
for (i = 0; i < len; i++) {
for (j = i; j > 0; j--) {
this.comparisons++;
this.midSort(arr, i, j);
this.ui.midsort(arr, i, j);
if (arr[j - 1] > arr[j]) {
this.swaps++;
@ -106,7 +108,7 @@ InsertionSort.prototype.sort = function(arr) {
arr[j - 1] = arr[j];
arr[j] = tmp;
this.swap(arr, j);
this.ui.swap(arr, j);
}
else {
break;
@ -114,6 +116,6 @@ InsertionSort.prototype.sort = function(arr) {
}
}
this.postSort(arr);
this.ui.postsort(arr);
return arr;
};

@ -2,82 +2,84 @@
*
*/
var MergeSort = function() {
//===== Action management.
//
this.reset = function(len) {
this
.instruct(Itemgroup.background, 0, 0, '#f00', 0, len)
.instruct(Itemgroup.opacity, 0, 0, 0, len, 1)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 2, '')
.instruct(Itemgroup.message, 0, 0, 3, '')
.instruct(Itemgroup.message, 0, 0, 4, '')
.instruct(Itemgroup.message, 0, 0, 5, 'Starting sort.');
};
//
this.preSort = function(start, mid, end, len) {
this
.instruct(Itemgroup.message, 0, 0, 2, `Sorting [${start}] - [${end}]`)
.instruct(Itemgroup.message, 0, 0, 3, 'Slicing and recursing...')
// .instruct(Itemgroup.message, 0, 0, 4, `[${start}]-[${mid}] and [${mid + 1}]-[${end}]`)
.instruct(Itemgroup.opacity, 0, 0, -1, start - 1, 0.2)
.instruct(Itemgroup.opacity, 0, 0, end + 1, len, 0.2)
.instruct(Itemgroup.opacity, 1, 0, 0, len, 0)
.instruct(Itemgroup.opacity, 2, 100, 0, len, 0)
};
//
this.preMerge = function(arr1, arr2, start, mid, end, len) {
var len1 = arr1.length;
var len2 = arr2.length;
for (var i = 0; i < len1; i++) {
this
.instruct(Itemgroup.text, 1, 0, i, arr1[i]);
}
for (var j = 0; j < len2; j++) {
this
.instruct(Itemgroup.text, 1, 0, len1 + j, arr2[j]);
}
this
.instruct(Itemgroup.message, 0, 0, 2, ``)
.instruct(Itemgroup.message, 0, 0, 3, 'Merging slices:')
.instruct(Itemgroup.message, 0, 0, 4, `[${start}]-[${mid}] and [${mid + 1}]-[${end}]`)
.instruct(Itemgroup.message, 0, 0, 5, '')
.instruct(Itemgroup.background, 1, 0, 0, len1 - 1, Visualizer.bg1)
.instruct(Itemgroup.background, 1, 0, len1, len1 + len2 - 1, '#751806')
.instruct(Itemgroup.opacity, 0, 0, 0, len, 0.2)
.instruct(Itemgroup.opacity, 1, 0, 0, len, 0)
.instruct(Itemgroup.opacity, 2, 0, 0, len, 0)
.instruct(Itemgroup.opacity, 1, 100, 0, len1 + len2 - 1, 1)
};
//
this.midMerge = function(indexG1, indexG2, value, message) {
this
.instruct(Itemgroup.opacity, 1, 0, indexG1, indexG1, 0)
.instruct(Itemgroup.opacity, 2, 0, indexG2, indexG2, 1)
.instruct(Itemgroup.text, 2, 0, indexG2, value)
.instruct(Itemgroup.message, 0, 0, 4, message)
.instruct(Itemgroup.message, 0, 100, 5, `${value} pushed onto sub-result.`);
};
//
this.updateComparisons = function() {
this.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${this.comparisons}`);
var _this = this;
this.ui = {
//
reset: function reset(len) {
_this
.instruct(Itemgroup.background, 0, 0, '#f00', 0, len)
.instruct(Itemgroup.opacity, 0, 0, 0, len, 1)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${_this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 2, '')
.instruct(Itemgroup.message, 0, 0, 3, '')
.instruct(Itemgroup.message, 0, 0, 4, '')
.instruct(Itemgroup.message, 0, 0, 5, 'Starting sort.');
},
//
presort: function presort(start, mid, end, len) {
_this
.instruct(Itemgroup.message, 0, 0, 2, `Sorting [${start}] - [${end}]`)
.instruct(Itemgroup.message, 0, 0, 3, 'Slicing and recursing...')
// .instruct(Itemgroup.message, 0, 0, 4, `[${start}]-[${mid}] and [${mid + 1}]-[${end}]`)
.instruct(Itemgroup.opacity, 0, 0, -1, start - 1, 0.2)
.instruct(Itemgroup.opacity, 0, 0, end + 1, len, 0.2)
.instruct(Itemgroup.opacity, 1, 0, 0, len, 0)
.instruct(Itemgroup.opacity, 2, 100, 0, len, 0)
},
//
premerge: function premerge(arr1, arr2, start, mid, end, len) {
var len1 = arr1.length;
var len2 = arr2.length;
for (var i = 0; i < len1; i++) {
_this
.instruct(Itemgroup.text, 1, 0, i, arr1[i]);
}
for (var j = 0; j < len2; j++) {
_this
.instruct(Itemgroup.text, 1, 0, len1 + j, arr2[j]);
}
_this
.instruct(Itemgroup.message, 0, 0, 2, ``)
.instruct(Itemgroup.message, 0, 0, 3, 'Merging slices:')
.instruct(Itemgroup.message, 0, 0, 4, `[${start}]-[${mid}] and [${mid + 1}]-[${end}]`)
.instruct(Itemgroup.message, 0, 0, 5, '')
.instruct(Itemgroup.background, 1, 0, 0, len1 - 1, Visualizer.bg1)
.instruct(Itemgroup.background, 1, 0, len1, len1 + len2 - 1, '#751806')
.instruct(Itemgroup.opacity, 0, 0, 0, len, 0.2)
.instruct(Itemgroup.opacity, 1, 0, 0, len, 0)
.instruct(Itemgroup.opacity, 2, 0, 0, len, 0)
.instruct(Itemgroup.opacity, 1, 100, 0, len1 + len2 - 1, 1)
},
//
midmerge: function midmerge(indexG1, indexG2, value, message) {
_this
.instruct(Itemgroup.opacity, 1, 0, indexG1, indexG1, 0)
.instruct(Itemgroup.opacity, 2, 0, indexG2, indexG2, 1)
.instruct(Itemgroup.text, 2, 0, indexG2, value)
.instruct(Itemgroup.message, 0, 0, 4, message)
.instruct(Itemgroup.message, 0, 100, 5, `${value} pushed onto sub-result.`);
},
//
updateComparisons: function updateComparisons() {
_this.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${_this.comparisons}`);
},
};
};
@ -118,7 +120,7 @@ MergeSort.prototype.init = function() {
*
*/
MergeSort.prototype.sort = function(arr, start, end) {
this.reset(arr.length);
this.ui.reset(arr.length);
if (arr.length === 0) {
return arr;
@ -130,11 +132,11 @@ MergeSort.prototype.sort = function(arr, start, end) {
var mid = start + Math.floor((end - start) / 2);
this.preSort(start, mid, end, arr.length);
this.ui.presort(start, mid, end, arr.length);
var arr1 = this.sort(arr, start, mid);
var arr2 = this.sort(arr, mid + 1, end);
this.preMerge(arr1, arr2, start, mid, end, arr.length);
this.ui.premerge(arr1, arr2, start, mid, end, arr.length);
var result = this.merge(arr1, arr2);
return result;
@ -156,33 +158,33 @@ MergeSort.prototype.merge = function(arr1, arr2) {
n = arr2.shift();
result.push(n);
this.midMerge(arr2index, result.length - 1, n, '(last element)');
this.ui.midmerge(arr2index, result.length - 1, n, '(last element)');
arr2index++;
}
else if (arr2.length === 0) {
n = arr1.shift();
result.push(n);
this.midMerge(arr1index, result.length - 1, n, '(last element)');
this.ui.midmerge(arr1index, result.length - 1, n, '(last element)');
arr1index++;
}
else if (arr1[0] <= arr2[0]) {
n = arr1.shift()
result.push(n);
this.midMerge(arr1index, result.length - 1, n, `Compare heads: ${n} <= ${arr2[0]}`);
this.ui.midmerge(arr1index, result.length - 1, n, `Compare heads: ${n} <= ${arr2[0]}`);
arr1index++;
}
else {
n = arr2.shift();
result.push(n);
this.midMerge(arr2index, result.length - 1, n, `Compare heads: ${arr1[0]} > ${n}`);
this.ui.midmerge(arr2index, result.length - 1, n, `Compare heads: ${arr1[0]} > ${n}`);
arr2index++;
}
this.comparisons++;
this.updateComparisons();
this.ui.updateComparisons();
}
return result;

@ -2,82 +2,85 @@
*
*/
var QuickSort = function() {
//===== Action management.
//
this.preSort = function(left, right, pivot, len) {
this
.instruct(Itemgroup.message, 0, 0, 1, 'Comparisons: ' + this.comparisons)
.instruct(Itemgroup.message, 0, 0, 2, 'Swaps: ' + this.swaps)
.instruct(Itemgroup.opacity, 1, 0, 0, len, 1)
.instruct(Itemgroup.opacity, 1, 0, -1, left - 1, 0.2)
.instruct(Itemgroup.opacity, 1, 0, right + 1, len, 0.2)
.instruct(Itemgroup.background, 1, 0, 0, this.ordered.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 3, 'Sorting from [' + left + '] to [' + right + ']')
.instruct(Itemgroup.message, 0, 0, 4, '')
.instruct(Itemgroup.message, 0, 100, 5, 'Starting sort.');
};
//
this.highlight = function(arr, left, right, pivot, msg) {
if (left >= right) {
return;
}
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.background, 1, 0, pivot, pivot, '#435C11')
.instruct(Itemgroup.background, 1, 0, left, left, '#0C1E42')
.instruct(Itemgroup.background, 1, 0, right, right, '#7F9EDB')
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 4, `Pivot at [${pivot}] = ${arr[pivot]}`)
.instruct(Itemgroup.message, 0, 100, 5, msg)
// .instruct(Itemgroup.message, 0, 0, 5, msg)
// .instruct(Itemgroup.message, 0, 100, 1, `Comparisons: ${this.comparisons}`)
};
//
this.stop = function(arr, left, right, pivot, msg) {
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.background, 1, 0, pivot, pivot, '#435C11')
.instruct(Itemgroup.background, 1, 0, left, left, '#0C1E42')
.instruct(Itemgroup.background, 1, 0, right, right, '#7F9EDB')
.instruct(Itemgroup.message, 0, 0, 4, `Pivot at [${pivot}] = ${arr[pivot]}`)
.instruct(Itemgroup.message, 0, 100, 5, msg)
};
//
this.swap = function(left, right) {
this
.instruct(Itemgroup.message, 0, 0, 2, 'Swaps: ' + this.swaps)
.instruct(Itemgroup.message, 0, 0, 4, 'Incremement left...')
.instruct(Itemgroup.message, 0, 0, 5, 'Decrement right...')
.instruct(Itemgroup.swap, 1, 300, left, right)
};
//
this.midSort = function(start, end, left, right) {
this
.instruct(Itemgroup.message, 0, 0, 3, 'Left has passed right.')
.instruct(Itemgroup.message, 0, 0, 4, `Recurse, sort from [${start}]-[${right}]`)
.instruct(Itemgroup.message, 0, 100, 5, `Recurse, sort from [${left}]-[${end}]`);
};
//
this.postSort = function() {
this
.instruct(Itemgroup.opacity, 1, 0, 0, this.ordered.length, 1)
.instruct(Itemgroup.background, 1, 0, 0, this.ordered.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 3, 'Sorting complete.')
.instruct(Itemgroup.message, 0, 0, 4, '')
.instruct(Itemgroup.message, 0, 0, 5, '');
};
var _this = this;
this.ui = {
//
presort: function presort(left, right, pivot, len) {
_this
.instruct(Itemgroup.message, 0, 0, 1, 'Comparisons: ' + _this.comparisons)
.instruct(Itemgroup.message, 0, 0, 2, 'Swaps: ' + _this.swaps)
.instruct(Itemgroup.opacity, 1, 0, 0, len, 1)
.instruct(Itemgroup.opacity, 1, 0, -1, left - 1, 0.2)
.instruct(Itemgroup.opacity, 1, 0, right + 1, len, 0.2)
.instruct(Itemgroup.background, 1, 0, 0, _this.ordered.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 3, 'Sorting from [' + left + '] to [' + right + ']')
.instruct(Itemgroup.message, 0, 0, 4, '')
.instruct(Itemgroup.message, 0, 100, 5, 'Starting sort.');
},
//
highlight: function highlight(arr, left, right, pivot, msg) {
if (left >= right) {
return;
}
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.background, 1, 0, pivot, pivot, '#435C11')
.instruct(Itemgroup.background, 1, 0, left, left, '#0C1E42')
.instruct(Itemgroup.background, 1, 0, right, right, '#7F9EDB')
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${_this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 4, `Pivot at [${pivot}] = ${arr[pivot]}`)
.instruct(Itemgroup.message, 0, 100, 5, msg)
// .instruct(Itemgroup.message, 0, 0, 5, msg)
// .instruct(Itemgroup.message, 0, 100, 1, `Comparisons: ${_this.comparisons}`)
},
//
stop: function stop(arr, left, right, pivot, msg) {
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.background, 1, 0, pivot, pivot, '#435C11')
.instruct(Itemgroup.background, 1, 0, left, left, '#0C1E42')
.instruct(Itemgroup.background, 1, 0, right, right, '#7F9EDB')
.instruct(Itemgroup.message, 0, 0, 4, `Pivot at [${pivot}] = ${arr[pivot]}`)
.instruct(Itemgroup.message, 0, 100, 5, msg)
},
//
swap: function swap(left, right) {
_this
.instruct(Itemgroup.message, 0, 0, 2, 'Swaps: ' + _this.swaps)
.instruct(Itemgroup.message, 0, 0, 4, 'Incremement left...')
.instruct(Itemgroup.message, 0, 0, 5, 'Decrement right...')
.instruct(Itemgroup.swap, 1, 300, left, right)
},
//
midsort: function midsort(start, end, left, right) {
_this
.instruct(Itemgroup.message, 0, 0, 3, 'Left has passed right.')
.instruct(Itemgroup.message, 0, 0, 4, `Recurse, sort from [${start}]-[${right}]`)
.instruct(Itemgroup.message, 0, 100, 5, `Recurse, sort from [${left}]-[${end}]`);
},
//
postsort: function postsort() {
_this
.instruct(Itemgroup.opacity, 1, 0, 0, _this.ordered.length, 1)
.instruct(Itemgroup.background, 1, 0, 0, _this.ordered.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 3, 'Sorting complete.')
.instruct(Itemgroup.message, 0, 0, 4, '')
.instruct(Itemgroup.message, 0, 0, 5, '');
},
}
};
QuickSort.prototype = Object.create(Sorter.prototype);
@ -114,7 +117,7 @@ QuickSort.prototype.init = function() {
*/
QuickSort.prototype.sort = function(arr, start, end) {
if (end <= start) {
this.postSort();
this.ui.postsort();
return arr;
}
@ -126,24 +129,24 @@ QuickSort.prototype.sort = function(arr, start, end) {
var tmp;
var rval;
this.preSort(left, right, pivot, arr.length);
this.ui.presort(left, right, pivot, arr.length);
while (left <= right) {
while (arr[left] < pivotval) {
this.comparisons++;
this.highlight(arr, left, right, pivot, `${arr[left]} < ${arr[pivot]}, increment left`);
this.ui.highlight(arr, left, right, pivot, `${arr[left]} < ${arr[pivot]}, increment left`);
left++;
}
this.stop(arr, left, right, pivot, `Left stop: ${arr[left]} >= ${arr[pivot]}`);
this.ui.stop(arr, left, right, pivot, `Left stop: ${arr[left]} >= ${arr[pivot]}`);
while (arr[right] > pivotval) {
this.comparisons++;
this.highlight(arr, left, right, pivot, `${arr[right]} > ${arr[pivot]}, decrement right`);
this.ui.highlight(arr, left, right, pivot, `${arr[right]} > ${arr[pivot]}, decrement right`);
right--;
}
this.stop(arr, left, right, pivot, `Right stop: ${arr[right]} <= ${arr[pivot]} `);
this.ui.stop(arr, left, right, pivot, `Right stop: ${arr[right]} <= ${arr[pivot]} `);
if (left <= right) {
tmp = arr[left];
@ -154,16 +157,16 @@ QuickSort.prototype.sort = function(arr, start, end) {
right--;
this.swaps++;
this.swap(left - 1, right + 1);
this.ui.swap(left - 1, right + 1);
}
}
this.midSort(start, end, left, right);
this.ui.midsort(start, end, left, right);
this.sort(arr, start, right);
this.sort(arr, left, end);
this.postSort();
this.ui.postsort();
return arr;
};

@ -2,62 +2,65 @@
*
*/
var SelectionSort = function() {
//===== Action management.
//
this.preSort = function(arr) {
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 3, ``)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, `Starting sort.`)
};
//
this.midSort = function(arr, i, j, min) {
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.background, 1, 0, j, j, Visualizer.bg1)
.instruct(Itemgroup.background, 1, 0, i, i, '#435C11')
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 3, `Current value: ${arr[i]}`)
.instruct(Itemgroup.message, 0, 0, 4, `Current minimum: ${arr[min]}`)
.instruct(Itemgroup.message, 0, 100, 5, `Comparing: ${arr[min]} and ${arr[j]}`)
};
//
this.newmin = function(arr, min) {
this
.instruct(Itemgroup.message, 0, 0, 4, `New minimum: ${arr[min]}`)
.instruct(Itemgroup.message, 0, 100, 5, ``)
};
//
this.swap = function(arr, i, min) {
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.background, 1, 0, i, i, Visualizer.bg1)
.instruct(Itemgroup.background, 1, 0, min, min, Visualizer.bg1)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 0, 5, `Swap current and minimum.`)
.instruct(Itemgroup.swap, 1, 300, i, min)
};
//
this.postSort = function(arr) {
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 3, ``)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, `Sorting complete.`)
var _this = this;
this.ui = {
//
presort: function presort(arr) {
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${_this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${_this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 3, ``)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, `Starting sort.`)
},
//
midsort: function midsort(arr, i, j, min) {
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.background, 1, 0, j, j, Visualizer.bg1)
.instruct(Itemgroup.background, 1, 0, i, i, '#435C11')
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${_this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 3, `Current value: ${arr[i]}`)
.instruct(Itemgroup.message, 0, 0, 4, `Current minimum: ${arr[min]}`)
.instruct(Itemgroup.message, 0, 100, 5, `Comparing: ${arr[min]} and ${arr[j]}`)
},
//
newmin: function newmin(arr, min) {
_this
.instruct(Itemgroup.message, 0, 0, 4, `New minimum: ${arr[min]}`)
.instruct(Itemgroup.message, 0, 100, 5, ``)
},
//
swap: function swap(arr, i, min) {
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.background, 1, 0, i, i, Visualizer.bg1)
.instruct(Itemgroup.background, 1, 0, min, min, Visualizer.bg1)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${_this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 0, 5, `Swap current and minimum.`)
.instruct(Itemgroup.swap, 1, 300, i, min)
},
//
postsort: function postsort(arr) {
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${_this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${_this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 3, ``)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, `Sorting complete.`)
},
};
};
@ -100,17 +103,17 @@ SelectionSort.prototype.sort = function(arr) {
var tmp;
var min;
this.preSort(arr);
this.ui.presort(arr);
for (i = 0; i < len; i++) {
min = i;
for (j = i + 1; j < len; j++) {
this.comparisons++;
this.midSort(arr, i, j, min);
this.ui.midsort(arr, i, j, min);
if (arr[j] < arr[min]) {
min = j;
this.newmin(arr, min);
this.ui.newmin(arr, min);
}
}
@ -120,11 +123,11 @@ SelectionSort.prototype.sort = function(arr) {
arr[i] = arr[min];
arr[min] = tmp;
this.swap(arr, i, min);
this.ui.swap(arr, i, min);
}
}
this.postSort(arr);
this.ui.postsort(arr);
return arr;
};

@ -2,57 +2,59 @@
*
*/
var ShellSort = function() {
//===== Action management.
//
this.preSort = function(arr, i, gap) {
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 3, `Gap: ${gap}`)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, `Starting sort at index ${i}.`)
};
//
this.midSort = function(arr, i, j, gap) {
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.background, 1, 0, j, j, Visualizer.bg1)
.instruct(Itemgroup.background, 1, 0, (j - gap), (j - gap), Visualizer.bg1)
.instruct(Itemgroup.message, 0, 0, 4, `Comparing [${j - gap}] and [${j}]`)
.instruct(Itemgroup.message, 0, 100, 5, ``)
};
//
this.swap = function(arr, j, gap) {
this
.instruct(Itemgroup.message, 0, 100, 4, `${arr[j]} < ${arr[j - gap]}, swap required.`)
.instruct(Itemgroup.swap, 1, 300, j - gap, j)
if (j - gap > 0) {
this
.instruct(Itemgroup.message, 0, 100, 5, `Continuing downstream...`)
var _this = this;
this.ui = {
presort: function presort(arr, i, gap) {
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${_this.comparisons}`)
.instruct(Itemgroup.message, 0, 0, 2, `Swaps: ${_this.swaps}`)
.instruct(Itemgroup.message, 0, 0, 3, `Gap: ${gap}`)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, `Starting sort at index ${i}.`)
},
//
midsort: function midsort(arr, i, j, gap) {
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.background, 1, 0, j, j, Visualizer.bg1)
.instruct(Itemgroup.background, 1, 0, (j - gap), (j - gap), Visualizer.bg1)
.instruct(Itemgroup.message, 0, 0, 4, `Comparing [${j - gap}] and [${j}]`)
.instruct(Itemgroup.message, 0, 100, 5, ``)
},
//
swap: function swap(arr, j, gap) {
_this
.instruct(Itemgroup.message, 0, 100, 4, `${arr[j]} < ${arr[j - gap]}, swap required.`)
.instruct(Itemgroup.swap, 1, 300, j - gap, j)
if (j - gap > 0) {
_this
.instruct(Itemgroup.message, 0, 100, 5, `Continuing downstream...`)
}
},
//
noswap: function noswap(arr, j, gap) {
_this
.instruct(Itemgroup.message, 0, 0, 4, `${arr[j]} > ${arr[j - gap]}, no swap required.`)
.instruct(Itemgroup.message, 0, 100, 5, ``)
},
//
postsort: function postsort(arr) {
_this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 3, ``)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, `Ready for insertion sort.`)
}
};
//
this.noswap = function(arr, j, gap) {
this
.instruct(Itemgroup.message, 0, 0, 4, `${arr[j]} > ${arr[j - gap]}, no swap required.`)
.instruct(Itemgroup.message, 0, 100, 5, ``)
};
//
this.postSort = function(arr) {
this
.instruct(Itemgroup.background, 1, 0, 0, arr.length, Visualizer.bg0)
.instruct(Itemgroup.message, 0, 0, 3, ``)
.instruct(Itemgroup.message, 0, 0, 4, ``)
.instruct(Itemgroup.message, 0, 100, 5, `Ready for insertion sort.`)
};
};
ShellSort.prototype = Object.create(Sorter.prototype);
@ -94,11 +96,11 @@ ShellSort.prototype.sort = function(arr) {
var i, j;
for (i = 0; i < gap; i++) {
this.preSort(arr, i, gap);
this.ui.presort(arr, i, gap);
this.gapSort(arr, i, gap);
}
this.postSort(arr);
this.ui.postsort(arr);
return arr;
};
@ -112,7 +114,7 @@ ShellSort.prototype.gapSort = function(arr, start, gap) {
for (i = start; i < len; i += gap) {
for (j = i; j > start; j -= gap) {
this.midSort(arr, i, j, gap);
this.ui.midsort(arr, i, j, gap);
this.comparisons++;
if (arr[j - gap] > arr[j]) {
@ -121,10 +123,10 @@ ShellSort.prototype.gapSort = function(arr, start, gap) {
arr[j - gap] = arr[j];
arr[j] = tmp;
this.swap(arr, j, gap);
this.ui.swap(arr, j, gap);
}
else {
this.noswap(arr, j, gap);
this.ui.noswap(arr, j, gap);
break;
}
}

@ -104,9 +104,8 @@ Visualizer.prototype.go = function() {
// TODO add links to stats
// TODO heap sort
// TODO disable next button if no further actions and during action
// TODO source code link and add all action management to .foo object in class
// TODO change pause/play state on slider change
// TODO radix sort
// TODO in quicksort, change color or element that is in final position
// NOTE functional programming discussion
// NOTE interesting (anti?)pattern here.

Loading…
Cancel
Save