冒泡排序

135 阅读4分钟

什么是冒泡排序?

经常看到这个名字,但是并不是什么了解,到底什么是冒泡排序。

其实很简单,就是在一个数组中,分别让每一位与自己的下一位做对比,如果比后面的数小,则不变位置,如果比后面的数大,则调换两个数的位置,直至把最大的那个数调到最后一个,就好像冒泡一样,最大的数冒出来了。

这样我们就可以通过这个方法,循环冒泡,直至这个数组的数进行升序或降序排列。

举个例子说明升序冒泡:

//如果有这样一个数组,里面有一组数字
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);

上面是升序排列,改变判断条件,进行对比,如果当前位小于后一位时调换位置则是降序,可以自己尝试进行。

有任何疑问或者不足欢迎批评指正。