原理
冒泡排序算法的基本思想为:假如待排序线性表的长度为 n,要使其从小到大排序,从前往后两两比较相邻元素的关键字,若第i+1个元素比第i个小,则交换它们,直到遍历整个线性表。每趟交换以后最后一个元素一定是最大的,不再参与下一趟交换。也就是对于第i 趟交换,只需要比较到 n-i即可。直到一趟比较内没有进行交换,算法结束。时间复杂度和插入排序一样,也为n^2。
不加flag
flag的作用是标示一趟比较内有没有进行交换,如果没有,则表示已经有序,排序可以直接结束,如果不加flag,也能完成排序,但就是强行比较(n*(n-1)/2)次了。
这种比较原始的实现方式,思路也很简单,用while
循环或for
循环都可以。使用while
循环时,每一趟比较完之后把数组长度变量-1,即最后一位元素已经排好序,不参与下次比较:
function bubbleSort1(arr) {
var len = arr.length;
var temp;
while (len > 0) {
for (var i =0; i < len-1; i++) {
if (arr[i+1] < arr[i]) {
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
len --;
}
}
如果使用for
循环,则是两层嵌套,第一层的数用来标示从最后一位起有几个数不用参与遍历交换,这个变量是不断增加的,内层的第二个变量则是用数组的全长减去外层变量,得出当前这趟遍历要到第几个元素:
function bubbleSor2(arr) {
var len = arr.length, temp;
for (var i = 0; i < len - 1; i++) {
for (var j = 0; j < len-i-1; j++) {
if (arr[j+1] < arr[j]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
优化:增加flag变量
在上面的实现方法的基础上增加flag变量,在每一趟比较之前置为false,如果中间进行了交换,则置为true,在循环条件中判断flag的值来决定要不要继续下一趟比较(或者根据flag值决定要不要跳出循环)
while循环:
function bubbleSor3(arr) {
var len = arr.length;
var temp, flag = false;
do {
flag = false;
for (var i =0; i < len-1; i++) {
if (arr[i+1] < arr[i]) {
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
flag = true;
}
}
len--;
} while (flag);
}
for循环:
function bubbleSort4(arr) {
var len = arr.length, temp, flag;
for (var i = 0; i < len - 1; i++) {
flag = false;
for (var j = 0; j < len - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag = true;
}
}
if (!flag) {
break;
}
}
}