什么是冒泡排序?
经常看到这个名字,但是并不是什么了解,到底什么是冒泡排序。
其实很简单,就是在一个数组中,分别让每一位与自己的下一位做对比,如果比后面的数小,则不变位置,如果比后面的数大,则调换两个数的位置,直至把最大的那个数调到最后一个,就好像冒泡一样,最大的数冒出来了。
这样我们就可以通过这个方法,循环冒泡,直至这个数组的数进行升序或降序排列。
举个例子说明升序冒泡:
//如果有这样一个数组,里面有一组数字
var arr = [24,8,65,5,47];
第一次对比 -> 24和8,得到:
arr = [8,24,65,5,47];
第二次对比 -> 24和65,得到:
arr = [8,24,65,5,47];
第三次对比 -> 65和5,得到:
arr = [8,24,5,65,47];
第四次对比 -> 65和47,得到:
arr = [8,24,5,47,65];
通过此种循环对比的方法,我们将该数组的最大值调到了最后一个。
那么,怎么将数组中的所有数字元素都按照从小到大的顺序排列呢?
我们只需要将上面的循环对比,再进行几次即可。
上面可以看到,我们已经将最大的数值放在了最后,所以进行第二次对比时,我们不需要对比最后一个数字了, 对比如下:
第二次循环对比:
arr = [8,24,5,47,65];
第一次对比 -> 8和24,得到:
arr = [8,24,5,47,65];
第二次对比 -> 24和5,得到:
arr = [8,5,24,47,65];
第三次对比 -> 24和47,得到:
arr = [8,5,24,47,65];
再进行第三次循环对比,同时我们不需要对比后面两项了:
arr = [8,5,24,47,65];
第一次对比 -> 8和5,得到:
arr = [5,8,24,47,65];
第二次对比 -> 8和24,得到:
arr = [5,8,24,47,65];
其实现在顺序已经排出来了,但是不排除某些情况在这一步仍未排序成功,所以我们还需要进行最后一次循环对比:
arr = [5,8,24,47,65];
最后一次对比 -> 5和8,得到:
arr = [5,8,24,47,65];
到现在为止,就已经大功告成了,原数组所有的数字元素,进行了升序排列。
但是真正在运用冒泡排序的过程中,我们不可能使用上述的方法,一步一步的进行书写,因为有的时候数组可能并不只这么几个数字而已,所以我们需要总结出规律,这样不管是多少位的数组,都能够一键排序。
在此之前,首先讲一下怎么给数组的前后两个元素调换位置
var arr= ['Tom','Jack'];
//如果想让Tom和Jack调换位置,需要利用一个中间值
//把Tom放进tmp中
var tmp = arr[0];
//将数组的第0位放入数组第一位的内容,也就是Jack
arr[0] = arr[1];
//把Tom放入数组第一位中;
arr[1] = tmp;
通过上面的方法,arr数组中,Tom 和 Jack 的位置就调换了。
好了,那么我们可以继续进行冒泡函数的书写了。
通过上面冒泡循环的例子,我们可以发现,我们一共进行了4次循环对比,正好比数组长度少1。
而第一次循环对比的次数,是4次,也就是数组长度减1,此时是循环的第1圈;
而第二次循环对比的次数,是3次,也就是数组长度减2,此时是循环的第2圈;
而第三次循环对比的次数,是3次,也就是数组长度减3,此时是循环的第3圈;
而第四次循环对比的次数,是1次,也就是数组长度减4,此时是循环的第4圈;
发现什么规律了吗?
每次循环对比的次数,正好等于数组的长度,减去循环的圈数。所以我们可以得到下面这个函数:
var arr = [5,9,4,33,7,2,1];
function getSort(arr){
//创建一个中间值,方便后面运用
var tmp;
//外层循环,控制循环对比的次数,一共是比数组长度少1次
for(var i = 1; i < arr.length;i ++){
//内层循环,每次循环对比,找出最大的值放在最后,每次循环的次数是数组长度减去外层循环的圈数
for(var j = 0; j < arr.length - i; j ++){
//如果当前位大于后一位时,进行调换位置
if(arr[j] > arr[j+1]){
tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
//返回升序排列的数组
return arr;
}
getSort(arr);
上面是升序排列,改变判断条件,进行对比,如果当前位小于后一位时调换位置则是降序,可以自己尝试进行。
有任何疑问或者不足欢迎批评指正。