|
|
|
@ -1,27 +1,123 @@ |
|
|
|
|
/** |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
var QuickSort = function(VisualizerInstance) { |
|
|
|
|
var QuickSort = function() { |
|
|
|
|
//===== Inits.
|
|
|
|
|
this.actions = []; |
|
|
|
|
|
|
|
|
|
this.swaps = 0; |
|
|
|
|
this.comparisons = 0; |
|
|
|
|
this.V = VisualizerInstance; |
|
|
|
|
|
|
|
|
|
this.V |
|
|
|
|
.instruct(this.V.hideMarker, 0, 1) |
|
|
|
|
.instruct(this.V.hideMarker, 0, 2) |
|
|
|
|
.instruct(this.V.message, 0, 2, 'Swaps: ' + this.swaps) |
|
|
|
|
.instruct(this.V.message, 0, 1, 'Comparisons: ' + this.comparisons); |
|
|
|
|
//===== 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, ''); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
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, ''); |
|
|
|
|
}; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
QuickSort.prototype = Object.create(Sorter.prototype); |
|
|
|
|
|
|
|
|
|
// NOTE adds to an instruction set
|
|
|
|
|
/** |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
QuickSort.prototype.init = function() { |
|
|
|
|
var len = this.shuffled.length; |
|
|
|
|
|
|
|
|
|
this |
|
|
|
|
.instruct(Itemgroup.items, 0, 0, len) |
|
|
|
|
.instruct(Itemgroup.items, 1, 0, len) |
|
|
|
|
.instruct(Itemgroup.items, 2, 0, len) |
|
|
|
|
|
|
|
|
|
for (var i = 0; i < len; i++) { |
|
|
|
|
this.instruct(Itemgroup.text, 1, 0, i, this.shuffled[i]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this |
|
|
|
|
.instruct(Itemgroup.foreground, 1, 0, 0, len, Visualizer.fg0) |
|
|
|
|
.instruct(Itemgroup.background, 1, 0, 0, len, Visualizer.bg0) |
|
|
|
|
|
|
|
|
|
.instruct(Itemgroup.opacity, 0, 0, 0, len, 0) |
|
|
|
|
.instruct(Itemgroup.opacity, 2, 0, 0, len, 0) |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
QuickSort.prototype.sort = function(arr, start, end) { |
|
|
|
|
if (end <= start) { |
|
|
|
|
// message: Left and Right have crossed, start sorting sublists.
|
|
|
|
|
this.postSort(); |
|
|
|
|
return arr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -29,94 +125,49 @@ QuickSort.prototype.sort = function(arr, start, end) { |
|
|
|
|
var right = end; |
|
|
|
|
|
|
|
|
|
var pivot = Math.floor((right + left) / 2); |
|
|
|
|
var pivotval = arr[pivot].value; |
|
|
|
|
var pivotval = arr[pivot]; |
|
|
|
|
var tmp; |
|
|
|
|
var rval; |
|
|
|
|
|
|
|
|
|
this.V |
|
|
|
|
.instruct(this.V.marker, 0, 1, left, 'L') |
|
|
|
|
.instruct(this.V.marker, 0, 2, right, 'R') |
|
|
|
|
|
|
|
|
|
.instruct(this.V.showMarker, 0, 1) |
|
|
|
|
.instruct(this.V.showMarker, 0, 2) |
|
|
|
|
|
|
|
|
|
.instruct(this.V.unhighlight, 0) |
|
|
|
|
.instruct(this.V.highlight, 0, pivot) |
|
|
|
|
|
|
|
|
|
.instruct(this.V.fade, 0, -1, start - 1) |
|
|
|
|
.instruct(this.V.fade, 0, end + 1, arr.length) |
|
|
|
|
// Message: pivot chosen
|
|
|
|
|
|
|
|
|
|
.instruct(this.V.message, 0, 3, 'Sorting from [' + start + '] to [' + end + ']') |
|
|
|
|
.instruct(this.V.message, 0, 4, '') |
|
|
|
|
.instruct(this.V.message, 100, 5, ''); |
|
|
|
|
// Message: pivot chosen
|
|
|
|
|
this.preSort(left, right, pivot, arr.length); |
|
|
|
|
|
|
|
|
|
while (left <= right) { |
|
|
|
|
|
|
|
|
|
this.V.instruct(this.V.message, 0, 4, ''); |
|
|
|
|
this.V.instruct(this.V.message, 0, 5, ''); |
|
|
|
|
|
|
|
|
|
while (arr[left].value < pivotval) { |
|
|
|
|
while (arr[left] < pivotval) { |
|
|
|
|
this.comparisons++; |
|
|
|
|
this.V |
|
|
|
|
.instruct(this.V.message, 0, 4, `${arr[left].value} < ${pivotval}, increment left` ) |
|
|
|
|
.instruct(this.V.message, 0, 1, `Comparisons: ${this.comparisons}`) |
|
|
|
|
.instruct(this.V.marker, 500, 1, left); |
|
|
|
|
|
|
|
|
|
this.highlight(arr, left, right, pivot, `${arr[left]} < ${arr[pivot]}, increment left`); |
|
|
|
|
left++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.V |
|
|
|
|
.instruct(this.V.message, 0, 4, `Left stop: ${arr[left].value} >= ${pivotval}`) |
|
|
|
|
.instruct(this.V.marker, 500, 1, left); |
|
|
|
|
this.stop(arr, left, right, pivot, `Left stop: ${arr[left]} >= ${arr[pivot]}`); |
|
|
|
|
|
|
|
|
|
while (arr[right].value > pivotval) { |
|
|
|
|
while (arr[right] > pivotval) { |
|
|
|
|
this.comparisons++; |
|
|
|
|
this.V |
|
|
|
|
.instruct(this.V.message, 0, 5, `${arr[right].value} > ${pivotval}, decrement right`) |
|
|
|
|
.instruct(this.V.message, 0, 1, 'Comparisons: ' + this.comparisons) |
|
|
|
|
.instruct(this.V.marker, 100, 2, right); |
|
|
|
|
|
|
|
|
|
this.highlight(arr, left, right, pivot, `${arr[right]} > ${arr[pivot]}, decrement right`); |
|
|
|
|
right--; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.V |
|
|
|
|
.instruct(this.V.message, 0, 5, `Right stop: ${arr[right].value} <= ${pivotval} `) |
|
|
|
|
.instruct(this.V.marker, 100, 2, right); |
|
|
|
|
this.stop(arr, left, right, pivot, `Right stop: ${arr[right]} <= ${arr[pivot]} `); |
|
|
|
|
|
|
|
|
|
if (left <= right) { |
|
|
|
|
tmp = arr[left]; |
|
|
|
|
arr[left] = arr[right]; |
|
|
|
|
arr[right] = tmp; |
|
|
|
|
|
|
|
|
|
this.V.instruct(this.V.swap, 100, left, right); |
|
|
|
|
|
|
|
|
|
left++; |
|
|
|
|
right--; |
|
|
|
|
|
|
|
|
|
this.swaps++; |
|
|
|
|
|
|
|
|
|
this.V |
|
|
|
|
.instruct(this.V.message, 0, 2, 'Swaps: ' + this.swaps) |
|
|
|
|
.instruct(this.V.message, 0, 4, 'Incremement left...') |
|
|
|
|
.instruct(this.V.message, 0, 5, 'Decrement right...') |
|
|
|
|
.instruct(this.V.marker, 100, 1, left) |
|
|
|
|
.instruct(this.V.marker, 100, 2, right) |
|
|
|
|
|
|
|
|
|
this.swap(left - 1, right + 1); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.V |
|
|
|
|
.instruct(this.V.unfade, 0) |
|
|
|
|
.instruct(this.V.unhighlight, 0) |
|
|
|
|
.instruct(this.V.hideMarker, 0, 1) |
|
|
|
|
.instruct(this.V.hideMarker, 0, 2) |
|
|
|
|
.instruct(this.V.message, 0, 3, 'Sorting complete.') |
|
|
|
|
.instruct(this.V.message, 0, 4, '') |
|
|
|
|
.instruct(this.V.message, 0, 5, ''); |
|
|
|
|
this.midSort(start, end, left, right); |
|
|
|
|
|
|
|
|
|
this.sort(arr, start, right); |
|
|
|
|
this.sort(arr, left, end); |
|
|
|
|
|
|
|
|
|
this.postSort(); |
|
|
|
|
|
|
|
|
|
return arr; |
|
|
|
|
}; |
|
|
|
|