javascript实现选择排序的可视化,要怎么实现currentCompareIndex的变化
来源:4-4 在近乎有序的数据上测试插入排序算法.
甲骨文_0001
2017-09-24
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
body{margin:0;overflow:hidden;}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript">
let canvas = document.getElementById('canvas');
let gd = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
function rand(n, m){
let s = n + Math.random() * (m - n);
return Math.floor(s);
}
let N = 60;
let arr = [];
for( let i = 0; i < N; i ++ ){
arr.push( rand(1, canvas.height) + 1 );
}
let orderedIndex = -1, currentCompareIndex = -1, currentMin = -1;
draw();
function draw(){
canvas.width = canvas.width;
let w = canvas.width / N;
for( let i = 0; i < arr.length; i ++ ){
let x = i * w, y = canvas.height - arr[i];
gd.fillStyle = 'gray';
if(i <= orderedIndex){
gd.fillStyle = 'red';
}
if( i == currentMin ){
gd.fillStyle = 'blue';
}
gd.fillRect( x, y, w - 1, arr[i] );
} // for i
}
let nowTurn = 0; // 第0轮
// 每一轮选择排序
function doSelectSort(){
let minIndex = nowTurn;
for( let i = nowTurn + 1; i < arr.length; i ++ ){
if( arr[minIndex] > arr[i] ){
minIndex = i;
currentMin = minIndex; // for循环速度快,一轮定时器里,currentMin只会显示一次
}
}
let tmp = arr[nowTurn];
arr[nowTurn] = arr[minIndex];
arr[minIndex] = tmp;
orderedIndex = nowTurn;
}
let timer = setInterval( function(){
if(nowTurn >= arr.length - 1){
clearInterval(timer);
nowTurn = arr.length - 1;
// 结束了
currentMin = -1;
}
doSelectSort();
draw();
nowTurn ++;
}, 300 );
/*
function select_sort(){
for( let i = 0; i < arr.length; i ++ ){
let minIndex = i;
for( let j = i + 1; j < arr.length; j ++ ){
if( arr[minIndex] > arr[j] ){
minIndex = j;
}
} // for j
let tmp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = tmp;
} // for i
}*/
</script>
</body>
</html>
/// java里面有sleep,但js没有sleep,只能通过setInterval每轮定时器里作一次选择排序,这一轮里currentCompareIndex我不知道该怎么可视化到界面上,波波老师帮忙看看,谢谢啦>_<
2回答
-
在这种机制下,如果要想做到“边排序,边渲染”,需要将算法运行的中间过程封装成一个结构,而不能仅仅对数据做封装。在每一轮新渲染中,程序先解析出当前算法运行的步骤,然后进行渲染,之后操作这个算法结构向后执行一步,进行下一轮渲染,以此类推。整个框架的结构改变还是很大的,基本上要让排序算法面目全非:)
有些同学使用有些“作弊“的方式,将每一步想要可视化的排序后的数据进行了保存,之后在渲染的过程中只需要调用数据就好了。虽然不够优雅,但也算解决了问题。是一个备选方案:)比如:http://www.imooc.com/article/20330
012017-09-25 -
曹儒士子
2020-05-06
有一个比较简单的解决方案,可以不用修改波波老师的动画逻辑。
timeoutWrapper() { return new Promise(resolve => { setTimeout(() => { resolve(); }, 16); }); },
在下面的 async function 中调用即可达到 sleep 的效果
00
相似问题