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回答

liuyubobobo

2017-09-25

在这种机制下,如果要想做到“边排序,边渲染”,需要将算法运行的中间过程封装成一个结构,而不能仅仅对数据做封装。在每一轮新渲染中,程序先解析出当前算法运行的步骤,然后进行渲染,之后操作这个算法结构向后执行一步,进行下一轮渲染,以此类推。整个框架的结构改变还是很大的,基本上要让排序算法面目全非:)


有些同学使用有些“作弊“的方式,将每一步想要可视化的排序后的数据进行了保存,之后在渲染的过程中只需要调用数据就好了。虽然不够优雅,但也算解决了问题。是一个备选方案:)比如:http://www.imooc.com/article/20330


0
1
甲骨文_0001
这么晚还不忘回复,非常感谢!
2017-09-25
共1条回复

曹儒士子

2020-05-06

有一个比较简单的解决方案,可以不用修改波波老师的动画逻辑。

timeoutWrapper() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve();
    }, 16);
  });
},

在下面的 async function 中调用即可达到 sleep 的效果

0
0

7个经典应用诠释Java算法精髓

课程重应用、重实践、重思维,真正应用于实际工作开发中

1888 学习 · 112 问题

查看课程