排序算法之冒泡排序

这里是传送门⇒总结:关于排序算法



平均时间复杂度 最优时间复杂度 最差时间复杂度 空间复杂度 稳定性
冒泡排序 O(n2) O(n2) O(n2) O(1) 稳定
优化后 O(n2) O(n) O(n2) O(1) 稳定


  • 算法描述
    • 从头开始,依次比较相邻元素,如果前者比较大,则交换两者位置
    • 比较一轮之后,最大的元素被“冒泡”到最后
    • 继续从头开始比较相邻元素,把倒数第二大的元素“冒泡”到倒数第二的位置
    • ...直到所有元素都冒泡完毕
  • JS实现
// 使用公用函数Swap
// 交换array[i]和array[j]
function Swap(array, i, j) {
    var temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}

// 此处传入的array会被直接改变
function BubbleSort(array) {
    var len = array.length;
    for (var i = 0; i < len - 1; i++) {
        for (var j = 0; j < len - i - 1; j++) {
            if (array[j] > array[j + 1]) {
                Swap(array, j, j + 1);
            }
        }
    }
}
  • 分析
    • 基操是键值的比较
    • 不管哪种情况下,键值的比较的次数都是
    • 任何情况下的时间复杂度都为T(n) = O(n2)
    • 而该排序是直接交换待排序列的元素位置,即原地排序,所以空间复杂度为O(1)
    • 而在相邻元素的比较中,只有当前者比后者大时才交换位置,所以一样大的元素的前后位置不会改变,即冒泡排序是一种稳定排序算法
  • 优化
    • 算法中加上一个didswap的变量,用来表明当前这一轮的所有键值比较中是否有需要交换位置的情况
    • 让diswap一开始为false
    • 当一轮比较中有任何需要交换元素的情况出现,那么就把didswap设为true
    • 在一轮比较之后判断didswap的值,如果为false,那么直接结束算法了
    • 因为在一轮比较之后,如果didswap还是false,这说明待排序列的相邻元素之间已经没有需要交换位置的情况了
    • 也就是说相邻元素之间现在都是“前者小于等于后者”的关系,即待排序列已经是一个升序序列了
    • 该优化可以把冒泡排序算法的最优时间复杂度变为O(n)
  • 优化版的JS实现
// 此处传入的array会被直接改变
function BubbleSortPlus(array) {
    var len = array.length;
    var didswap;
    for (var i = 0; i < len - 1; i++) {
        didswap = false;
        for (var j = 0; j < len - i - 1; j++) {
            if (array[j] > array[j + 1]) {
                Swap(array, j, j + 1);
                didswap = true;
            }
        }
        if (!didswap) {
            break;
        }
    }
}
posted @ 2021-02-23 21:34  有机物与鱼  阅读(72)  评论(0编辑  收藏  举报