echarts-gl
Version:
Extension pack of ECharts providing 3D plots and globe visualization
129 lines (108 loc) • 3.43 kB
JavaScript
function swap(arr, a, b) {
var tmp = arr[a];
arr[a] = arr[b];
arr[b] = tmp;
}
function partition(arr, pivot, left, right, compare) {
var storeIndex = left;
var pivotValue = arr[pivot];
// put the pivot on the right
swap(arr, pivot, right);
// go through the rest
for(var v = left; v < right; v++) {
if(compare(arr[v], pivotValue) < 0) {
swap(arr, v, storeIndex);
storeIndex++;
}
}
// finally put the pivot in the correct place
swap(arr, right, storeIndex);
return storeIndex;
}
function quickSort(array, compare, left, right) {
if(left < right) {
var pivot = Math.floor((left + right) / 2);
var newPivot = partition(array, pivot, left, right, compare);
quickSort(array, compare, left, newPivot - 1);
quickSort(array, compare, newPivot + 1, right);
}
}
// TODO Test.
function ProgressiveQuickSort() {
// this._pivotList = new LinkedList();
this._parts = [];
}
ProgressiveQuickSort.prototype.step = function (arr, compare, frame) {
var len = arr.length;
if (frame === 0) {
this._parts = [];
this._sorted = false;
// Pick a start pivot;
var pivot = Math.floor(len / 2);
this._parts.push({
pivot: pivot,
left: 0,
right: len - 1
});
this._currentSortPartIdx = 0;
}
if (this._sorted) {
return;
}
var parts = this._parts;
if (parts.length === 0) {
this._sorted = true;
// Already finished.
return true;
}
else if (parts.length < 512) {
// Sort large parts in about 10 frames.
for (var i = 0; i < parts.length; i++) {
// Partition and Modify the pivot index.
parts[i].pivot = partition(
arr, parts[i].pivot, parts[i].left, parts[i].right, compare
);
}
var subdividedParts = [];
for (var i = 0; i < parts.length; i++) {
// Subdivide left
var left = parts[i].left;
var right = parts[i].pivot - 1;
if (right > left) {
subdividedParts.push({
pivot: Math.floor((right + left) / 2),
left: left, right: right
});
}
// Subdivide right
var left = parts[i].pivot + 1;
var right = parts[i].right;
if (right > left) {
subdividedParts.push({
pivot: Math.floor((right + left) / 2),
left: left, right: right
});
}
}
parts = this._parts = subdividedParts;
}
else {
// console.time('sort');
// Finally quick sort each parts in 10 frames.
for (var i = 0; i < Math.floor(parts.length / 10); i++) {
// Sort near parts first.
var idx = parts.length - 1 - this._currentSortPartIdx;
quickSort(arr, compare, parts[idx].left, parts[idx].right);
this._currentSortPartIdx++;
// Finish sort
if (this._currentSortPartIdx === parts.length) {
this._sorted = true;
return true;
}
}
// console.timeEnd('sort');
}
return false;
};
ProgressiveQuickSort.sort = quickSort;
export default ProgressiveQuickSort;