冒泡排序算法

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

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

        排序流程:以下以序列: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("\n排序后:");
        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("\n排序时长:"+(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
posted @ 2018-02-07 22:51  人情世故  阅读(333)  评论(0编辑  收藏  举报
"不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!"