面试_算法_冒泡排序

86 阅读2分钟

基本思想

冒泡排序会遍历n次要排序的数列,每次都从前往后依次比较相邻两个数的大小;如果前者比后者大,则交换它们的位置。这样,一次遍历之后,最大的元素就在数列的末尾! 采用相同的方法再次遍历,就能确定第二大的元素。重复此操作,直到整个数列都有序为止!

(第tt次遍历需遍历nt+1n-t+1个元素)



算法性能分析

1、时间复杂度

  • 最坏情况:待排序数列逆序。这样需要n-1次排序,第i趟排序需要进行nin-i次元素的比较。而且每次比较都需要移动3个元素,这种情况下,比较次数=n(n1)/2n(n-1)/2 ,移动次数=3n(n1)3n(n-1)。即时间复杂度为O(n2)O(n^2)
  • 最好情况:待排序列正序。设置flag标记。第一趟排序后if语句始终不成立,flag依旧为0,从而直接跳出外层循环,程序结束。比较次数为n1n-1,移动次数为0,故时间复杂度为O(n)O(n)
  • 平均情况:O(n2)O(n^2)

2、空间复杂度

​ 额外辅助空间只有一个temp或哨兵。因此空间复杂度为O(1)O(1)

\3. 稳定性

​ 是稳定的,但如果if语句中改用 大于(小于)等于 号,就是不稳定的,故不能改。



优化

设置一个哨兵,如果发现某一趟没有发生交换,则说明全部的排序已经完成!即可提前退出程序。



代码实现

import java.util.Arrays;

public class A {
    static int[] arr = {1, 5, 3, 2, -7, 8, 0, 9, 4, 6};
    static int len = 10;

    public static void swap(int[] arr, int a, int b) {
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }

    static void bubbleSort1() {
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < len - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    swap(arr, j, j + 1);  //将数组中的两个数交换
                }
            }
        }
    }

    // 冒泡排序的改进,设置一个标记,如果发现某一趟没有发生交换,则说明排序已经完成!即可提前退出
    static void bubbleSort2() {
        for (int i = 0; i < len; i++) {
            int flag = 0;
            for (int j = 0; j < len - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    flag = 1;
                    swap(arr, j, j + 1); //将数组中的两个数交换
                }
            }
            if (flag == 0) {
                break;
            }
        }
    }

    public static void main(String[] args) {
        //bubbleSort1();
        bubbleSort2();
        System.out.println(Arrays.toString(arr));
    }
}