冒泡排序的几种实现

原理

冒泡排序算法的基本思想为:假如待排序线性表的长度为 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;
        }
    }
}
点赞