【算法】——冒泡排序算法,深入详解(Java、Python两种语言实现)

冒泡排序算法

依次比较相邻的两个数,将小数放在前面,大数放在后面,直到将最大数放在最后,然后进行第二趟比较

第一趟排序:

  • 将序列中的第一个元素与第二个元素比较
  • 如果第一个元素 > 大于第二个元素,则交换
  • 然后比较第二个元素与第三个元素,以此类推
  • 直到第 N-1 个与第 N 个元素比较完为止,然后进行第二趟排序

第二趟排序:

  • 重复上述操作,以此类推
  • 直到第 N-2个元素与第 N-1个元素比较完为止,然后进行第三趟排序

......

以上我们可以看出,每次需要比较的元素都在不断减少,因为我们每一趟排序都会把最大的元素交换到后面合适的位置,所以后面已经交换好的元素不用再参与下次循环了

也就是下面代码第二层 for 循环中的(数组长度 - i - 1)

  • 减 i 的作用就是上面我们说的比较好的元素不再进行下次比较,所以下次比较的元素不断减少。
  • 因为我们每次比较的都是当前元素和后一个元素,所以只需要遍历到倒数第二个元素即可,因此进行减 1 操作。

若共有 N 个元素,则需进行 N 趟比较

然后第一趟中再需要 N-1 次比较,第二趟需要 N-2次比较......

 

时间复杂度

最好情况:O(n²),因为即使是个有序数组,也需要都检查一遍

平均情况:O(n²)

最坏情况:O(n²),是一个倒序的数组,每个都需要进行交换

改进后代码的时间复杂度

(下面会提到改进后的代码)

最好情况:O(n),是一个正序的数组

平均情况:O(n²)

最坏情况:O(n²),是一个倒序的数组,每个都需要进行交换

Python代码 

"""冒泡排序"""
# 升序
ls = [5, 2, 0, 1, 3, 1, 4]
for i in range(len(ls)):
    for j in range(len(ls) - i - 1):
        if ls[j] > ls[j + 1]:
            temp = ls[j]
            ls[j] = ls[j + 1]
            ls[j + 1] = temp
print(ls)

 Java代码

package algorithm;

public class Sort {

    // 冒泡排序算法,升序
    public static void bubbleSort(int[] array) {
        for (int i = 0 ; i < array.length ; i++) {
            for (int j = 0 ; j < array.length - i - 1 ; j++) {
                if (array[j] > array[j + 1]) {
                    int temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
        }
    }

    public static void main(String[] args) {
        int[] array = new int[]{5, 2, 0, 1, 3, 1, 4};
        Sort.bubbleSort(array);
        // 打印数组
        for (int i = 0 ; i < array.length ; i++) {
            System.out.print(array[i] + " ");
        }
    }
}

改进后的Java代码

通过以上代码我们发现,假如,待排序列已经是有序的,或者在排序的过程中,循环还没有结束就已经有序了,那么我们已经不需要再继续循环下去了,此时直接退出即可

因此,我们需要一个标志,来检测待排序列是否有序

public static void bubbleSort(int[] array) {
        boolean flag;
        for (int i = 0 ; i < array.length ; i++) {
            flag = true;
            for (int j = 0 ; j < array.length - i - 1 ; j++) {
                if (array[j] > array[j + 1]) {
                    int temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                    flag = false;
                }
            }
            // 如果flag为true,则说明没有进入第二层循环
            // 也就是待排数组已经是有序的,所以直接退出即可
            if (flag) {
                break;
            }
        }
    }

此时的时间复杂度最优情况已经可以达到 O(n) 了

发布了22 篇原创文章 · 获赞 17 · 访问量 5846

猜你喜欢

转载自blog.csdn.net/weixin_42193813/article/details/104995631