冒泡排序(包括两种优化)

说明

  • 稳定性:稳定
  • 时间复杂度:最好-O(n);最坏O(n^2);平均O(n^2);
  • 空间复杂度:O(1)
  • 使用场景:数据规模小的场景
  • 算法思想:比较相邻的两个元素,将较小的数交换到左端,直到序列有序。
  • 实现说明:包含两层循环,每次外层循环冒出最大的一个数到length-1-i的位置,内存循环,每次比较相邻两个数,将较大数换到后面直到length-i-1位置。
  • 优化说明:包括两种优化,优化外层循环和优化内层循环。

1.代码实现

public static void main(String[] args) {
        //产生0-9随机序列
        final int MAX_SIZE = 10;
        int[] list = new int[MAX_SIZE];
        System.out.println("待排序列:");
        for(int i = 0;i<list.length;i++) {
                list[i] = (int)(Math.random()*MAX_SIZE);   
            System.out.print(list[i] + " ");
        }
        //排序
        //表示每次循环都冒出一个最小(大)的数
        for (int i = 0; i < list.length; i++) {  
        //将最大的数冒到右端(两两交换)
            for(int j = 0;j<list.length-i-1;j++) { 
                if (list[j] > list[j+1]) {
                    int temp = list[j];
                    list[j] = list[j+1];
                    list[j+1] = temp;
                }
            }
        }
        //打印有序序列
        System.out.println("\n有序序列");
        for (int i = 0; i < list.length; i++) {
            System.out.print(list[i]+" ");
        }

    }

2.优化外层循环

可以知道,如果某次循环没有进行数据交换,那么序列已经有序,后面的循环不需要再执行。因此可以用一个变量来记录是否发生了交换。

public static void main(String[] args) {
        boolean flag = true;                           //表示是否继续循环变量
        //产生0-9随机序列
        final int MAX_SIZE = 10;
        int[] list = new int[MAX_SIZE];
        System.out.println("待排序列:");
        for(int i = 0;i<list.length;i++) {
            list[i] = (int)(Math.random()*MAX_SIZE);   
            System.out.print(list[i] + " ");
        }
        //排序
        //表示每次循环都找出一个最小(大)的数
        for (int i = 0; i < list.length && flag; i++) {  
            flag = false;
            //将最大的数冒到右端(两两交换)
            for(int j = 0; j <list.length - i - 1;j++) { 
                if (list[j] > list[j+1]) {
                    int temp = list[j];
                    list[j] = list[j+1];
                    list[j+1] = temp;
                    //如果进行了交换则继续,该方法需要多进行一次无用循环,用来判断是否有序
                    flag = true;                   
                }
            }
        }
        //打印有序序列
        System.out.println("\n有序序列");
        for (int i = 0; i < list.length; i++) {
            System.out.print(list[i]+" ");
        }
    }

3.优化内层循环

可以知道某次循环交换的最后一次的后面的值是有序的,因此我们可以记录这个位置,在后面的循环我们只用交换到这个位置即可。

public static void main(String[] args) {
        // 产生随机序列
        final int MAX_SIZE = 10;
        int[] list = new int[MAX_SIZE];
        Random random = new Random();
        System.out.println("待排序列:");
        for (int i = 0; i < list.length; i++) {
            list[i] = random.nextInt(MAX_SIZE);
            System.out.print(list[i] + " ");
        }
        // 排序
        // 记录每次的last值
        int pos = list.length - 1;
        // 保存上一次冒泡的last值
        int last;
        for (int i = 0; i < list.length; i++) {
            last = pos;
            // 根据上次的last值其后的数不需要交换
            for (int j = 0; j < last; j++) {
                if (list[j] > list[j + 1]) {
                    int temp = list[j];
                    list[j] = list[j + 1];
                    list[j + 1] = temp;
                    pos = j;
                }
            }
        }
        // 打印有序序列
        System.out.println("\n有序序列");
        for (int i = 0; i < list.length; i++) {
            System.out.print(list[i] + " ");
        }
    }

4.两种优化方式结合

    public static void main(String[] args) {
        // 产生随机序列
        final int MAX_SIZE = 10;
        int[] list = new int[MAX_SIZE];
        Random random = new Random();
        System.out.println("待排序列:");
        for (int i = 0; i < list.length; i++) {
            list[i] = random.nextInt(MAX_SIZE);
            System.out.print(list[i] + " ");
        }
        // 排序
        // 记录每次的last值
        int pos = list.length - 1;
        // 保存上一次冒泡的last值
        int last;
        // 记录是否发生了交换
        boolean flag = true;
        for (int i = 0; i < list.length && flag; i++) {
            last = pos;
            flag = false;
            for (int j = 0; j < last; j++) {
                if (list[j] > list[j + 1]) {
                    int temp = list[j];
                    list[j] = list[j + 1];
                    list[j + 1] = temp;
                    pos = j;
                    flag = true;
                }
            }
        }
        // 打印有序序列 
        System.out.println("\n有序序列");
        for (int i = 0; i < list.length; i++) {
            System.out.print(list[i] + " ");
        }
    }

}

猜你喜欢

转载自blog.csdn.net/rbreeze/article/details/80298331