From 4c28ba0029f7578ace45f8467bf6c689823a8241 Mon Sep 17 00:00:00 2001 From: ben-burlingham Date: Wed, 28 Oct 2015 07:29:50 -0700 Subject: [PATCH] Mergesort finished. Re-architected to better suit mergesort, radixsort. --- js/mergesort.js | 106 +++++++++++++++++++++++++++--------------------- js/sorter.js | 4 +- 2 files changed, 62 insertions(+), 48 deletions(-) diff --git a/js/mergesort.js b/js/mergesort.js index 14258f2..620fef5 100644 --- a/js/mergesort.js +++ b/js/mergesort.js @@ -8,15 +8,11 @@ var MergeSort = function() { //===== Action management. // - this.reset = function(arr, start, end) { - var len = arr.length; - + this.reset = function(len) { this .instruct(Itemgroup.background, 0, 0, '#f00', 0, len) .instruct(Itemgroup.opacity, 0, 0, 0, len, 1) - .instruct(Itemgroup.opacity, 0, 0, -1, start - 1, 0.2) - .instruct(Itemgroup.opacity, 0, 0, end + 1, len, 0.2) .instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${this.comparisons}`) .instruct(Itemgroup.message, 0, 0, 2, '') @@ -25,44 +21,62 @@ var MergeSort = function() { .instruct(Itemgroup.message, 0, 0, 5, ''); }; - // - this.splitSingle = function(index) { - this - .instruct(Itemgroup.message, 0, 100, 2, `Single element [${index}]`); - }; // - this.preSort = function(start, mid, end) { + 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, 100, 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, 1, 0, 0, len, 0) + .instruct(Itemgroup.opacity, 2, 100, 0, len, 0) }; // - this.preMerge = function(start, mid, end, len) { + 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, 1, 0, start, end, 1) .instruct(Itemgroup.opacity, 2, 0, 0, len, 0) - }; - // - this.postMerge = function(len) { - this - .instruct(Itemgroup.opacity, 1, 0, 0, len, 0) + .instruct(Itemgroup.opacity, 1, 100, 0, len1 + len2 - 1, 1) }; // - this.midMerge = function(index, value, message) { + this.midMerge = function(indexG1, indexG2, value, message) { this - .instruct(Itemgroup.opacity, 1, 0, index, index, 1) - .instruct(Itemgroup.text, 1, 0, index, value) - .instruct(Itemgroup.message, 0, 100, 5, `Pushing ${value} to sub-result.`); + .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.`); }; // @@ -92,49 +106,37 @@ MergeSort.prototype.init = function() { .instruct(Itemgroup.foreground, 0, 0, 0, len, Visualizer.fg0) .instruct(Itemgroup.background, 0, 0, 0, len, Visualizer.bg0) - .instruct(Itemgroup.opacity, 1, 0, 0, 0, len) + .instruct(Itemgroup.opacity, 1, 0, 0, len, 0) .instruct(Itemgroup.foreground, 1, 0, 0, len, Visualizer.fg1) .instruct(Itemgroup.background, 1, 0, 0, len, Visualizer.bg1) - .instruct(Itemgroup.opacity, 2, 0, 0, 0, len) + .instruct(Itemgroup.opacity, 2, 0, 0, len, 0) .instruct(Itemgroup.foreground, 2, 0, 0, len, Visualizer.fg2) - .instruct(Itemgroup.background, 2, 100, 0, len, Visualizer.bg2) - - - this - .instruct(Itemgroup.swap, 0, 1000, 0, 1) - .instruct(Itemgroup.swap, 0, 1000, 1, 2) - .instruct(Itemgroup.swap, 0, 1000, 2, 3) - .instruct(Itemgroup.swap, 0, 1000, 3, 2) - .instruct(Itemgroup.swap, 0, 1000, 2, 1) - .instruct(Itemgroup.swap, 0, 1000, 1, 0) + .instruct(Itemgroup.background, 2, 100, 0, len, Visualizer.bg2); }; /** * */ MergeSort.prototype.sort = function(arr, start, end) { - this.reset(arr, start, end); + this.reset(arr.length); if (arr.length === 0) { return arr; } if (start === end) { - this.splitSingle(start); return [arr[start]]; } - var mid = start + Math.floor((end - start) / 2); - this.preSort(start, mid, end); + this.preSort(start, mid, end, arr.length); var arr1 = this.sort(arr, start, mid); var arr2 = this.sort(arr, mid + 1, end); - this.preMerge(start, mid, end, arr.length); + this.preMerge(arr1, arr2, start, mid, end, arr.length); var result = this.merge(arr1, arr2); - this.postMerge(arr.length); return result; }; @@ -146,26 +148,38 @@ MergeSort.prototype.merge = function(arr1, arr2) { var result = []; var n; + // (For reporting only, to keep track of "split" group.) + var arr1index = 0; + var arr2index = arr1.length; + while (arr1.length > 0 || arr2.length > 0) { if (arr1.length === 0) { n = arr2.shift(); result.push(n); - this.midMerge(result.length, n, 'One element left to merge.'); + + this.midMerge(arr2index, result.length - 1, n, '(last element)'); + arr2index++; } else if (arr2.length === 0) { n = arr1.shift(); result.push(n); - this.midMerge(result.length, n, 'One element left to merge.'); + + this.midMerge(arr1index, result.length - 1, n, '(last element)'); + arr1index++; } else if (arr1[0] <= arr2[0]) { n = arr1.shift() result.push(n); - this.midMerge(result.length, n, `${n} <= ${arr2[0]}`); + + this.midMerge(arr1index, result.length - 1, n, `Compare heads: ${n} <= ${arr2[0]}`); + arr1index++; } else { n = arr2.shift(); result.push(n); - this.midMerge(result.length, n, `${arr1[0]} > ${n}`); + + this.midMerge(arr2index, result.length - 1, n, `Compare heads: ${arr1[0]} > ${n}`); + arr2index++; } this.comparisons++; diff --git a/js/sorter.js b/js/sorter.js index 292173c..5138b2c 100644 --- a/js/sorter.js +++ b/js/sorter.js @@ -63,7 +63,7 @@ Sorter.prototype.instruct = function() { Sorter.prototype.generate = function(n) { this.data = []; - var upper = Math.floor(Math.random() * 300 + n); + var upper = Math.floor(Math.random() * 300 + 100 + n); for (var i = 0; i < n; i++) { this.data.push(Math.floor(i * upper / n)); }; @@ -71,7 +71,7 @@ Sorter.prototype.generate = function(n) { this.shuffled = this.shuffle(this.data); this.ordered = this.shuffled.slice(); this.init(); - // this.sort(this.ordered, 0, this.ordered.length - 1); + this.sort(this.ordered, 0, this.ordered.length - 1); return this.actions; };