我正在尝试使用画布来可视化JavaScript中的排序算法? [英] I am trying to use canvas to visualize sort algorithm in javascript?

查看:72
本文介绍了我正在尝试使用画布来可视化JavaScript中的排序算法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出于娱乐目的,我试图可视化排序算法,但遇到了问题。

For fun I am trying to visualize a sorting algorithm, but I have run into an issue.

我试图在sort方法中调用draw函数,但浏览器锁定并仅呈现最终排序的数组。如何可视化排序的每个过程?

I tried to call the draw function in the sort method but the browser locks up and renders only the final sorted array. How can I visualize every process of sorting?

var CANVAS_WIDTH = window.innerWidth;
var CANVAS_HEIGHT = window.innerHeight;

var canvas = document.querySelector('canvas')
var context = canvas.getContext('2d');

canvas.width = CANVAS_WIDTH;
canvas.height = CANVAS_HEIGHT;

context.fillStyle = 'red';
context.fillRect(0,0, CANVAS_WIDTH, CANVAS_WIDTH);

function draw(array){
    context.save();
    context.clearRect(0, 0, canvas.width, canvas.height);
    context.strokeStyle = 'white';
    context.beginPath();
    context.moveTo(0, canvas.height-100);
    context.lineTo(canvas.width, canvas.height-100);
    context.stroke();
    context.restore();
    context.fillStyle = 'white';
    for(let i = 0; i < array.length; i++){
        context.fillRect(100 + 7*i,canvas.height-100,5,-5 * array[i]);
    }
}




let array = []

for(let i = 0; i < 100; i++){
    array.push(100-i);
}
function bubble_Sort(arr){
    let ticks = 0;  
    const speed = 50;
    let size = arr.length;
    for(let i = 0; i < size; i++){
        ticks++;
        for(let j = 0; j < size - 1; j++){
            draw(array);
            if (arr[j] > arr[j+1]){
                let temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
    return arr;
}
draw(array);
array = bubble_Sort(array)


推荐答案

您可以使用 async await 进行此操作:这样,您就不必触摸(很多)现有代码。只需使bubble_Sort函数与关键字 async 异步,然后在循环中添加 await delay()即可。 delay 函数应该是一个返回可在短时延迟内解决的承诺的函数。

You can use async await for that: that way you don't have to touch (much) your existing code. Just make the bubble_Sort function asynchronous with the keyword async, and add an await delay() in the loop. The delay function should then be a function that returns a promise that resolves within a short delay.

作为旁注,您可以加快气泡的速度。内部循环不应重新访问已排序的数组部分。每次外部循环执行一个循环时,值都会到达数组最右端的最后一个点,因此内部循环可以在到达该位置之前停止。

As a side note, you can speed up your bubble sort a bit. The inner loop should not revisit the part of the array that is already sorted. Each time the outer loop makes a cycle, a value arrives at its final spot at the righter end of the array, so the inner loop can stop before reaching that position.

您还可以保存绘图上的一点点:执行交换时仅调用 draw ,因为两次绘制相同情况没有用。

You can also save a bit on the drawing: only call draw when you perform a swap, as there is no use in drawing the same situation twice.

以下是您的代码,其中包含以下内容:

Here is your code with those adaptations:

// Utility function:
let delay = ms => new Promise(resolve => setTimeout(resolve, ms));
// Make the main function async
async function bubble_Sort(arr){
    // Move the initial call of draw here
    draw(array);
    await delay(5); // <---- asynchronous delay of a few milliseconds
    let size = arr.length;
    for(let i = 0; i < size; i++){
        for(let j = 0; j < size - 1 - i; j++){ // optimised algo a bit! 
            if (arr[j] > arr[j+1]){
                let temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
                // Only draw when something changed
                draw(array);
                await delay(5); // <---- asynchronous delay of a few milliseconds
            }
        }
    }
    return arr;
}

function draw(array) { // Just simplified it for this demo. Nothing essential.
    context.clearRect(0, 0, canvas.width, canvas.height);
    for(let i = 0; i < array.length; i++){
        context.fillRect(10 + 7*i,canvas.height-20,5,-array[i]);
    }
}

var CANVAS_WIDTH = window.innerWidth - 10;
var CANVAS_HEIGHT = window.innerHeight - 70;
var canvas = document.querySelector('canvas')
var context = canvas.getContext('2d');
canvas.width = CANVAS_WIDTH;
canvas.height = CANVAS_HEIGHT;
context.fillStyle = 'red';

let array = [...Array(80).keys()].reverse();
// skip a draw call here, and
// Don't assign to array, since bubble_Sort now returns a promise
bubble_Sort(array).then(sorted => console.log(...sorted));

<canvas></canvas>

这篇关于我正在尝试使用画布来可视化JavaScript中的排序算法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆