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> <br>
<h2>Quicksort discussion</h2> <h2>Quicksort discussion</h2>
<p>
used by chrome.<br>
source code link
</p>
<p>used by chrome.</p>
<div class="sorter" <div class="sorter"
data-algorithm='quick' data-algorithm='quick'
data-stable='Maybe' data-stable='Maybe'
@ -30,10 +33,13 @@
data-worst-memory='0 (in place)' data-worst-memory='0 (in place)'
></div> ></div>
<h2>Mergesort discussion</h2> <h2>Mergesort discussion</h2>
<p>used by firefox and safari. </p> <p>
helpful: http://stackoverflow.com/questions/2967153/space-requirements-of-a-merge-sort<br> 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" <div class="sorter"
data-algorithm='merge' data-algorithm='merge'
data-stable='Maybe' data-stable='Maybe'
@ -44,37 +50,49 @@
data-worst-memory='0 (in place)' data-worst-memory='0 (in place)'
></div> ></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" <div class="sorter"
data-algorithm='shell' data-algorithm='selection'
data-stable='Maybe' data-stable='Maybe'
data-adaptive='Maybe' data-adaptive='Maybe'
data-worst-perf='O(n + m + 3k)' data-worst-perf='O(n + m + 3k)'
data-avg-perf='O(n + m + 3k)' data-avg-perf='O(n + m + 3k)'
data-best-perf='O(n + m + 3k)' data-best-perf='O(n + m + 3k)'
data-worst-memory='0 (in place)' data-worst-memory='0 (in place)'>
></div> </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" <div class="sorter"
data-algorithm='selection' data-algorithm='insertion'
data-stable='Maybe' data-stable='Maybe'
data-adaptive='Maybe' data-adaptive='Maybe'
data-worst-perf='O(n + m + 3k)' data-worst-perf='O(n + m + 3k)'
data-avg-perf='O(n + m + 3k)' data-avg-perf='O(n + m + 3k)'
data-best-perf='O(n + m + 3k)' data-best-perf='O(n + m + 3k)'
data-worst-memory='0 (in place)'> data-worst-memory='0 (in place)'
</div> ></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" <div class="sorter"
data-algorithm='insertion' data-algorithm='shell'
data-stable='Maybe' data-stable='Maybe'
data-adaptive='Maybe' data-adaptive='Maybe'
data-worst-perf='O(n + m + 3k)' data-worst-perf='O(n + m + 3k)'
@ -85,8 +103,12 @@
<h2>Bubble sort discussion</h2> <h2>Bubble sort discussion</h2>
how is this different from insertion and selection sorts. <br> <p>
talk about turtles and rabbits, because search loops from beginning each time. Every number out of place means a new pass must be done. 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" <div class="sorter"
data-algorithm='bubble' data-algorithm='bubble'
data-stable='Maybe' data-stable='Maybe'

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

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

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

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

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

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

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

Loading…
Cancel
Save