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.
 
 
 

191 lines
5.8 KiB

/**
*
*/
var MergeSort = function() {
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}`);
},
};
};
MergeSort.prototype = Object.create(Sorter.prototype);
/**
*
*/
MergeSort.prototype.init = function() {
var len = this.shuffled.length;
this.actions = [];
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, 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, 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, len, 0)
.instruct(Itemgroup.foreground, 2, 0, 0, len, Visualizer.fg2)
.instruct(Itemgroup.background, 2, 100, 0, len, Visualizer.bg2);
};
/**
*
*/
MergeSort.prototype.sort = function(arr, start, end) {
this.ui.reset(arr.length);
if (arr.length === 0) {
return arr;
}
if (start === end) {
return [arr[start]];
}
var mid = start + Math.floor((end - start) / 2);
this.ui.presort(start, mid, end, arr.length);
var arr1 = this.sort(arr, start, mid);
var arr2 = this.sort(arr, mid + 1, end);
this.ui.premerge(arr1, arr2, start, mid, end, arr.length);
var result = this.merge(arr1, arr2);
return result;
};
/**
*
*/
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.ui.midmerge(arr2index, result.length - 1, n, '(last element)');
arr2index++;
}
else if (arr2.length === 0) {
n = arr1.shift();
result.push(n);
this.ui.midmerge(arr1index, result.length - 1, n, '(last element)');
arr1index++;
}
else if (arr1[0] <= arr2[0]) {
n = arr1.shift()
result.push(n);
this.ui.midmerge(arr1index, result.length - 1, n, `Compare heads: ${n} <= ${arr2[0]}`);
arr1index++;
}
else {
n = arr2.shift();
result.push(n);
this.ui.midmerge(arr2index, result.length - 1, n, `Compare heads: ${arr1[0]} > ${n}`);
arr2index++;
}
this.comparisons++;
this.ui.updateComparisons();
}
return result;
};