zoukankan      html  css  js  c++  java
  • 冒泡排序算法

      前面两篇介绍了两个非常简单和基础的排序算法——选择排序和插入排序,除了这两个,冒泡排序也是非常简单的一种排序算法。同样,本篇主要从“基本原理、排序流程、核心代码、算法性能、稳定性、参考代码”等几个方面介绍这一算法。

             基本原理:依次比较两个相邻元素的大小,如果前一个元素大于(或小于)后一个元素,则两个元素交换位置。这样每一趟都能确定一个最大(或最小)的元素,每一趟都能把最大(或最小)的元素放到最后,直到所有元素都有序为止。

            排序流程:以下以序列:5 3 0 4 1 9 7 2 6 8为例,加粗元素表示每一趟参与比较的元素,未加粗元素表示已经排好的元素(未参与比较),红色元素表示每一趟排好的最大元素。

    趟数 排序前 排序后 说明
    1 5 3 0 4 1 9 7 2 6 8 3 0 4 1 5 7 2 6 8 9 9元素最大,移动到最后面位置,此时9元素位置已定
    2 3 0 4 1 5 7 2 6 8 9 0 3 1 4 5 2 6 7 8 9 8元素最大,移动到9元素前面位置,8元素位置已定
    3 0 3 1 4 5 2 6 7 8 9 0 1 3 4 2 5 6 7 8 9 7元素最大,移动到8元素前面位置,7元素位置已定
    4 0 1 3 4 2 5 6 7 8 9 0 1 3 2 4 5 6 7 8 9 6元素最大,移动到7元素前面位置,6元素位置已定
    5 0 1 3 2 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 5元素最大,移动到6元素前面位置,5元素位置已定
    6 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 4元素最大,移动到5元素前面位置,4元素位置已定
    7 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 3元素最大,移动到4元素前面位置,3元素位置已定
    8 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 2元素最大,移动到3元素前面位置,2元素位置已定
    9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 1元素最大,移动到2元素前面位置,1元素位置已定

            最终排序结果为:0 1 2 3 4 5 6 7 8 9。最后一趟由于只比较了前两个元素,后面所有元素都已有序,所以此趟结束之后,序列已经有序了。需要注意的是,每一趟排序都能确定最大(或最小)的元素,但发生移动的元素可能不仅仅是最大(或最小)的元素,比如第一趟中5元素的位置发生改变。可以看出,如果序列长度为N,则总共进行了N-1趟排序,每一趟都能确定一个元素,所以下一趟参与比较的元素会比上一趟少一个。

            核心代码:以Java为例。

    复制代码
    public static void sort(int[] a){
        int n = a.length;  //序列长度
        for (int i = 0; i < n-1; i++){  //排序趟数
            for (int j = 0; j < n-i-1; j++){
                if (a[j + 1] < a[j]){
                      int temp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = temp;
                }
            }
        }
    }
    复制代码

            算法性能:对于所有元素都相等或者已经有序的序列,只会进行(N-1)+(N-2)+……+1=N(N-1)/2次比较,不会发生任何移动;对于逆序序列,同样会进行N(N-1)/2次比较,但每次比较都会交换元素,每次交换都会移动两个元素,所以会有N(N-1)次移动。总的来说,时间复杂度为O(N²),空间复杂度为O(1)。

             稳定性:冒泡排序就是不断把大的元素移动到序列后面的过程,每次比较都是相邻的两个元素比较,交换也是相邻的两个元素交换。所以如果序列中有两个或多个元素相等,排序的时候不会发生交换;如果两个或多个相等的元素没有相邻,那么即使通过前面的两两交换把它们相邻起来,它们之间也不会发生交换,这样相等的元素相对位置并没有改变,所以冒泡排序是稳定的。

            参考代码:以Java为例。

    复制代码
    import java.util.Random;
    
    /*
     * 冒泡排序
     */
    public class BubbleSort {
        public static void sort(int[] a){
            int n = a.length;  //序列长度
            for (int i = 0; i < n-1; i++){  //排序趟数
                for (int j = 0; j < n-i-1; j++){
                    if (a[j + 1] < a[j]){
                        int temp = a[j];
                        a[j] = a[j + 1];
                        a[j + 1] = temp;
                    }
                }
            }
        }
        public static void main(String[] args) {
            Random random = new Random();
            int[] arg1 = new int[20];
            for(int n=0;n<20;n++){  //从[0-100]中生成20个随机数
                arg1[n] = random.nextInt(100);
            }
            System.out.println("排序前:");
            for (int i = 0; i < arg1.length; i++) {
                System.out.print(arg1[i]+" ");
            }
            System.out.println("
    排序后:");
            long startTime = System.currentTimeMillis();  //获取开始时间
            sort(arg1);
            long endTime = System.currentTimeMillis();  //获取结束时间
            for (int i = 0; i < arg1.length; i++) {
                System.out.print(arg1[i]+" ");
            }
            System.out.println("
    排序时长:"+(endTime-startTime)+"ms");
        }
    }
    复制代码

            运行结果:

    排序前:
    83 13 36 11 58 75 68 43 73 72 24 81 98 14 27 23 1 46 60 3 
    排序后:
    1 3 11 13 14 23 24 27 36 43 46 58 60 68 72 73 75 81 83 98 
    排序时长:0ms
    zhuanzi http://www.cnblogs.com/Y-oung/p/7820294.html
  • 相关阅读:
    鸟哥的Linux私房菜基础学习篇(第三版)——阅读笔记(二)
    鸟哥的Linux私房菜基础学习篇(第三版)——阅读笔记(一)
    Git的使用流程及常用命令汇总
    Protocol buffers编写风格指南
    Effective Go中文版(更新中)
    go package 学习笔记 —— strconv(string与其他基本数据类型(int, float, bool)的转换)
    在iis上部署 AngularJS
    asp.net Core 2.0部署到iis上
    ABP 运行前端代码
    Asp.NET Core2.0 EF ABP Postgresql 数据迁移
  • 原文地址:https://www.cnblogs.com/shizhijie/p/8428811.html
Copyright © 2011-2022 走看看