我正在使用 p5.js 开发排序可视化工具,我需要知道是否可以减慢合并排序,以便可以更慢地绘制它。我目前正在尝试使用下面的睡眠功能来减慢它们的合并功能,但我得到
未捕获的类型错误:a.slice 不是函数。
我只是犯了一个愚蠢的错误,还是我错误地处理了这个问题?
let rectWidth;
let depth = 0;
function setup() {
let numOfRects = document.getElementById('numOfRects').value;
let width = document.getElementById('canvas').offsetWidth;
let height = document.getElementById('canvas').offsetHeight;
let canvas = createCanvas(width, height);
rectWidth = floor(width / numOfRects);
canvas.parent('canvas');
values = new Array(floor(width / rectWidth));
for (let i = 0; i < values.length; i++) {
values[i] = random(height);
}
frameRate(1);
}
function draw() {
background(23);
values = mergeSort(values, depth);
depth++;
for (let i = 0; i < values.length; i++) {
stroke(0);
fill(255);
rect(i * rectWidth, height - values[i], rectWidth, values[i]);
}
}
function mergeSort(a, d) {
if (a.length <= 1) {
return a;
}
d--;
if (d < 1) {
return (a);
}
var mid = Math.round((a.length / 2));
var left = a.slice(0, mid);
var right = a.slice(mid);
let leArr = mergeSort(left, d);
let riArr = mergeSort(right, d);
return merge(leArr, riArr);
}
async function merge(left, right) {
sorted = [];
while (left && left.length > 0 && right && right.length > 0) {
if (left[0] <= right[0]) {
sorted.push(left.shift());
} else {
sorted.push(right.shift());
}
}
await sleep(50);
return sorted.concat(left, right);
}
async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
合并算法中的睡眠根本没有意义。您的绘制函数只能绘制由返回的最终数组mergeSort
。因此,即使你让算法变慢,你也不会看到任何中间结果,直到mergeSort
尚未完成指定深度。
一种可能性是做归并排序 https://en.wikipedia.org/wiki/Merge_sort在一个单独的线程中并可视化draw
数组的当前状态。但在这种情况下,您必须对“原始”数组应用排序,而不是创建数组的副本(通过slice
)并在最后将它们写回原始数组。
参见示例:
let values = [];
let startSort = true;
function mergeSort(a) {
// create copy of the array
copy = a.slice()
// asynchronous sort the copy
mergeSortSlice(copy, 0, copy.length);
return;
}
async function mergeSortSlice(a, start, end) {
if (end-start <= 1)
return;
var mid = Math.round((end+start) / 2);
// wait till divides are sort
await mergeSortSlice(a, start, mid);
await mergeSortSlice(a, mid, end);
// merge divides
let i = start, j = mid;
while (i < end && j < end) {
if (a[i] > a[j]) {
let t = a[j]; a.splice(j, 1); a.splice(i, 0, t);
j ++;
}
i ++;
if (i==j) j ++;
// copy back the current state of the sorting
values = a.slice();
// slow down
await sleep(100);
}
// restart
if (start == 0 && end == a.length) {
await sleep(2000);
startSort = true;
}
}
async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function setup() {
createCanvas(600, 190);
frameRate(60);
}
let numOfRects = 15;
let rectWidth;
function draw() {
if (startSort) {
startSort = false;
rectWidth = floor(width / numOfRects);
values = new Array(floor(width / rectWidth));
for (let i = 0; i < values.length; i++) {
values[i] = random(height);
}
mergeSort(values);
}
background(23);
stroke(0);
fill(255);
for (let i = 0; i < values.length; i++) {
rect(i * rectWidth, height - values[i], rectWidth, values[i]);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)