You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
5.3 KiB
169 lines
5.3 KiB
/**
|
|
*
|
|
*/
|
|
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, '');
|
|
};
|
|
};
|
|
|
|
QuickSort.prototype = Object.create(Sorter.prototype);
|
|
|
|
/**
|
|
*
|
|
*/
|
|
QuickSort.prototype.init = function() {
|
|
var len = this.shuffled.length;
|
|
|
|
this.actions = [];
|
|
this.swaps = 0;
|
|
this.comparisons = 0;
|
|
|
|
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) {
|
|
this.postSort();
|
|
return arr;
|
|
}
|
|
|
|
var left = start;
|
|
var right = end;
|
|
|
|
var pivot = Math.floor((right + left) / 2);
|
|
var pivotval = arr[pivot];
|
|
var tmp;
|
|
var rval;
|
|
|
|
this.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`);
|
|
left++;
|
|
}
|
|
|
|
this.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`);
|
|
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;
|
|
|
|
left++;
|
|
right--;
|
|
this.swaps++;
|
|
|
|
this.swap(left - 1, right + 1);
|
|
}
|
|
}
|
|
|
|
this.midSort(start, end, left, right);
|
|
|
|
this.sort(arr, start, right);
|
|
this.sort(arr, left, end);
|
|
|
|
this.postSort();
|
|
|
|
return arr;
|
|
};
|
|
|