冒泡排序算法可视化
在百度前端技术学院的任务列表那里看到了有一个任务是要求用javascript实现可视化的排序算法,感觉很有趣,就稍微研究了一下.
冒泡排序原理
冒泡排序我们应该都不陌生吧?很简单的两个for循环就可以实现了,其基本原理是:在一开始的时候,比较第一第二个数,如果如果第一个数比第二个数大的话则交换二者位置,在比较第二个和第三个数,同样的如果第二个数比第三个数大的话,则交换二者位置,如此重复,所以一趟比较下来就能筛选出最大的一个数并把它排在最后的位置,又因为一个for循环的话只能选出一个最大的数,而我们还需要选出第二大、第三大...到最小的数,所以还需要加一个for循环才能实现我们的目标。用javascript实现就是:
/*冒泡排序*/ function bubbleSort(arr){ if(arr.length<=1){ return arr; }; var temp=0; for(var i=0; i<arr.length; i++){ for(var j=0; j<arr.length-i-1; j++){ if(arr[j]>arr[j+1]){ temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; }; }; }; return arr; };
可视化原理
接下来就是要用可视化的方式把排序的过程展现出来了。我们可以用这两种方法去实现它:
1 排序的每一步结束后,我们让程序暂停一下运行(javascript没有sleep函数,我们需要自己去实现它),这样子的话,在我们看来排序的过程就是一步一步的进行的,就不会一瞬间就排序结束了。
2 我们可以通过维护一个数组,把每一次排序之后的数组保存起来,在排序算法结束之后,我们再把保存的每一个数组依次绘制出来。我这里的实现用的就是这种方法。
var snapshots=[]; //快照集合
var timer=null; //定时
var arr=[50,21,5,89,13,35,69,44,60,15,51,80,55,71]; //排序数组
/*冒泡排序*/ function bubbleSort(arr){ if(arr.length<=1){ return arr; }; var temp=0; for(var i=0; i<arr.length; i++){ for(var j=0; j<arr.length-i-1; j++){ if(arr[j]>arr[j+1]){ temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; snapshots.push(JSON.parse(JSON.stringify(arr))); //<=记录下快照 }; }; }; return arr; };
Array.prototype.bubbleSort=function(){
return bubbleSort(this);
}
我们设置一个snapshots数组变量,用于记录下每一次排序之后数组的快照,等排序结束之后,我们就能得到一组记录下完整的排序过程的数组的快照了,这个时候我们再按照一定的时间间隔依次把这些快照绘制出来,就能实现出排序过程的可视化了。
/*绘图*/ function painting(){ var container=document.getElementById("container"); var bars=[].slice.call( document.querySelectorAll(".bar") ); //将所有bar元素的集合转换为数组对象 for(var i=0;i<arr.length;i++){ if(bars.length!=arr.length){ var bar=document.createElement("div"); bar.className="bar"; container.appendChild(bar); }else{ break; //当bar的数量等于数组的长度时,停止创建bar元素 }; }; var snapshot=snapshots.shift() || []; //取出快照记录数组中的第一条记录 console.log(snapshot); if(snapshot.length!=0){ for(var i=0; i<bars.length; i++){ bars[i].innerHTML=snapshot[i]; bars[i].style.height=snapshot[i]*5+"px"; bars[i].style.left=(i+1)*50+"px"; }; }else{ clearInterval(timer); //绘制结束 return; }; }; arr.bubbleSort(); //排序 timer=setInterval(painting,200); //定时绘制
效果图:
附上演示地址:http://jerellin.github.io/visualization.html