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.
 
 
 

176 lines
5.0 KiB

/**
*
*/
var MergeSort = function() {
//===== Inits.
this.actions = [];
this.comparisons = 0;
//===== Action management.
//
this.reset = function(arr, start, end) {
var len = arr.length;
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, '')
.instruct(Itemgroup.message, 0, 0, 3, '')
.instruct(Itemgroup.message, 0, 0, 4, '')
.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
.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}]`);
};
//
this.preMerge = function(start, mid, end, len) {
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.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)
};
//
this.midMerge = function(index, 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.`);
};
//
this.updateComparisons = function() {
this.instruct(Itemgroup.message, 0, 0, 1, `Comparisons: ${this.comparisons}`);
};
};
MergeSort.prototype = Object.create(Sorter.prototype);
/**
*
*/
MergeSort.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, 0, 0, i, this.shuffled[i]);
}
this
.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.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.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)
};
/**
*
*/
MergeSort.prototype.sort = function(arr, start, end) {
this.reset(arr, start, end);
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);
var arr1 = this.sort(arr, start, mid);
var arr2 = this.sort(arr, mid + 1, end);
this.preMerge(start, mid, end, arr.length);
var result = this.merge(arr1, arr2);
this.postMerge(arr.length);
return result;
};
/**
*
*/
MergeSort.prototype.merge = function(arr1, arr2) {
var result = [];
var n;
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.');
}
else if (arr2.length === 0) {
n = arr1.shift();
result.push(n);
this.midMerge(result.length, n, 'One element left to merge.');
}
else if (arr1[0] <= arr2[0]) {
n = arr1.shift()
result.push(n);
this.midMerge(result.length, n, `${n} <= ${arr2[0]}`);
}
else {
n = arr2.shift();
result.push(n);
this.midMerge(result.length, n, `${arr1[0]} > ${n}`);
}
this.comparisons++;
this.updateComparisons();
}
return result;
};