diff --git a/index.html b/index.html index dc0c019..e63c829 100644 --- a/index.html +++ b/index.html @@ -18,8 +18,11 @@

Quicksort discussion

+

+ used by chrome.
+ source code link +

-

used by chrome.

-

Mergesort discussion

-

used by firefox and safari.

- helpful: http://stackoverflow.com/questions/2967153/space-requirements-of-a-merge-sort
+

+ used by firefox and safari.
+ helpful: http://stackoverflow.com/questions/2967153/space-requirements-of-a-merge-sort
+ source code link +

+
+

Selection sort discussion

+

+ http://stackoverflow.com/questions/15799034/insertion-sort-vs-selection-sort
+ finds upstram minimum and swaps with current.
+ source code link +

-

Shellsort discussion

- several ways to pick gap width, but dependence on input data makes gap selection trivial.
+ data-worst-memory='0 (in place)'> + + +

Insertion sort discussion

+

+ how is this different from bubble and selection.
+ swap. highlight. fade.
+ source code link +

-

Selection sort discussion

- http://stackoverflow.com/questions/15799034/insertion-sort-vs-selection-sort
- finds upstram minimum and swaps with current.
-
+ data-worst-memory='0 (in place)' + > + +

Shellsort discussion

+

+ several ways to pick gap width, but dependence on input data makes gap selection trivial.
+ Insertion sort with gap of 1.
+ source code link +

-

Insertion sort discussion

- how is this different from bubble and selection.
- swap. highlight. fade.
Bubble sort discussion - how is this different from insertion and selection sorts.
- 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.
+ talk about turtles and rabbits, because search loops from beginning each time. Every number out of place means a new pass must be done.
+ source code link +

+
${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; }; diff --git a/js/insertionsort.js b/js/insertionsort.js index 76d1171..51dd5fa 100644 --- a/js/insertionsort.js +++ b/js/insertionsort.js @@ -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; }; diff --git a/js/mergesort.js b/js/mergesort.js index 8a221de..37e1bab 100644 --- a/js/mergesort.js +++ b/js/mergesort.js @@ -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; diff --git a/js/quicksort.js b/js/quicksort.js index 1dff8ba..1c7f374 100644 --- a/js/quicksort.js +++ b/js/quicksort.js @@ -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; }; diff --git a/js/selectionsort.js b/js/selectionsort.js index e95039b..5579f31 100644 --- a/js/selectionsort.js +++ b/js/selectionsort.js @@ -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; }; diff --git a/js/shellsort.js b/js/shellsort.js index 0489a40..b9dfb1a 100644 --- a/js/shellsort.js +++ b/js/shellsort.js @@ -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; } } diff --git a/js/visualizer.js b/js/visualizer.js index 12c1207..d8b36a4 100644 --- a/js/visualizer.js +++ b/js/visualizer.js @@ -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.