冒泡排序算法可视化

在百度前端技术学院的任务列表那里看到了有一个任务是要求用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

 

posted @ 2016-04-01 21:43  Levitt  阅读(5227)  评论(2编辑  收藏  举报