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

    冒泡排序的基本思想:

    在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大 的数往下沉 ,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。

    关于程序中4中冒泡排序写法的说明:

    bubble_sort1:基本的冒泡排序的写法。

    bubble_sort2:基本冒泡排序的不同写法,基本的冒泡排序是每次遍历,每次缩小范围1,这种办法是每次正向和反向遍历,每次缩小范围2,所以两者的比较次数也是一样的。

    bubble_sort3:如果在某一趟的冒泡途中没有出现数据交换,那就只能是数据已经被排好序了,这样就可以提前得知数据排好序从而中断循环,消除掉不必要的比较。

    bubble_sort4:如果在某一趟的冒泡途中最后的交换出现在pos的位置,那么表示pos位置以后都已经排好序,这样相比于基本冒泡每一次缩小遍历范围1而言有可能一次缩小的遍历范围>=1,所以这样也可以提高排序的效率。

    程序代码如下:

      1 package mecrt.study.collection.sort;
      2 
      3 /**
      4  * 冒泡排序
      5  */
      6 public class BubbleSort {
      7     public static void main(String[] args) {
      8 
      9         int[] a = {3,5,1,2,4,9,6,8,10,7};
     10         int[] b = {3,5,1,2,4,9,6,8,10,7};
     11         int[] c = {3,5,1,2,4,9,6,8,10,7};
     12         int[] d = {3,5,1,2,4,9,6,8,10,7};
     13         System.out.println("
    初始值:");
     14         print(a);
     15         int count1 = dubbleSort1(a);
     16         System.out.println("排序后:");
     17         print(a);
     18         System.out.println("dubbleSort1比较次数"+count1);
     19         
     20         
     21         System.out.println("
    初始值:");
     22         print(b);
     23         int count2 = dubbleSort2(b);
     24         System.out.println("排序后:");
     25         print(b);
     26         System.out.println("dubbleSort2比较次数"+count2);
     27         
     28         System.out.println("
    初始值:");
     29         print(c);
     30         int count3 = dubbleSort3(c);
     31         System.out.println("排序后:");
     32         print(c);
     33         System.out.println("dubbleSort3比较次数"+count3);
     34         
     35         System.out.println("
    初始值:");
     36         print(d);
     37         int count4 = dubbleSort4(d);
     38         System.out.println("排序后:");
     39         print(d);
     40         System.out.println("dubbleSort4比较次数"+count4);
     41     }
     42      
     43     /**
     44      * 最基本的冒泡排序
     45      * @param data
     46      */
     47     public static int dubbleSort1(int[] data){
     48         int count = 0;
     49         //冒泡一次放好一个数,冒泡data.length-1次,数组排序完成
     50         for (int i = 0; i < data.length-1; i++) {
     51             //后面i个数已经冒泡完成,为有序数列,不需要再次进行冒泡
     52             for (int j = 0; j < data.length-1-i; j++,count++) {
     53                 //相邻元素想比较,进行冒泡
     54                 if(data[j]>data[j+1]){
     55                     swap(data, j, j+1);
     56                 }
     57             }
     58         }
     59         return count;
     60     }
     61     
     62     /**
     63      * 双向冒泡排序
     64      *  @param data
     65      */
     66     public static int dubbleSort2(int[] data){
     67         int low = 0;
     68         int high = data.length-1;
     69         int j,count=0;
     70         while(low<high){
     71             for (j=low; j < high; j++, count++) {
     72                 if(data[j]>data[j+1]){
     73                     swap(data, j, j+1);
     74                 }
     75             }
     76             high--;
     77             for (j = high; j > low; j--,count++) {
     78                 if(data[j]<data[j-1]){
     79                     swap(data, j, j-1);
     80                 }
     81             }
     82             low++;
     83         }
     84         return count;
     85     }
     86     
     87     /**
     88      * 冒泡排序,如果在某一趟的冒泡途中没有出现数据交换,
     89      * 那就只能是数据已经被排好序了,
     90      * 这样就可以提前得知数据排好序从而中断循环,
     91      * 消除掉不必要的比较。
     92      * @param data
     93      * @return
     94      */
     95     public static int dubbleSort3(int[] data){
     96         int i,j,count = 0;
     97         boolean exchange = true;
     98         for (i = 0; i < data.length-1&&exchange; i++) {
     99             for (j = 0,exchange = false; j < data.length-1-i; j++,count++) {
    100                 if(data[j]>data[j+1]){
    101                     swap(data, j, j+1);
    102                     exchange = true;
    103                 }
    104             }
    105         }
    106         return count;
    107     }
    108     
    109     /**
    110      * 如果在某一趟的冒泡途中最后的交换出现在pos的位置,
    111      * 那么表示pos位置以后都已经排好序,
    112      * 这样相比于基本冒泡每一次缩小遍历范围1而言有可能一次缩小的遍历范围>=1,
    113      * 所以这样也可以提高排序的效率。
    114      * @param data
    115      * @return
    116      */
    117     public static int dubbleSort4(int[] data){
    118         int i,j,pos = 0,count = 0;
    119         for (i = 0; i < data.length-1; i = data.length - 1 - pos) {
    120             for (j = 0,pos = 0; j < data.length-1-i; j++,count++) {
    121                 if(data[j]>data[j+1]){
    122                     swap(data, j, j+1);
    123                     pos = j+1;
    124                 }
    125             }
    126         }
    127         return count;
    128     }
    129     public static void swap(int[] data,int i,int j){
    130         if(i == j ){
    131             return ;
    132         }
    133         data[i] = data[i] + data[j];
    134         data[j] = data[i] - data[j];
    135         data[i] = data[i] - data[j];
    136     }
    137     
    138     private static void print(int[] a){
    139         for (int i = 0; i < a.length; i++) {
    140             System.out.print(a[i]+"  ");
    141         }
    142         System.out.println();
    143     }
    144 }

    运行结果:

    初始值:
    3  5  1  2  4  9  6  8  10  7  
    排序后:
    1  2  3  4  5  6  7  8  9  10  
    dubbleSort1比较次数45
    
    初始值:
    3  5  1  2  4  9  6  8  10  7  
    排序后:
    1  2  3  4  5  6  7  8  9  10  
    dubbleSort2比较次数45
    
    初始值:
    3  5  1  2  4  9  6  8  10  7  
    排序后:
    1  2  3  4  5  6  7  8  9  10  
    dubbleSort3比较次数30
    
    初始值:
    3  5  1  2  4  9  6  8  10  7  
    排序后:
    1  2  3  4  5  6  7  8  9  10  
    dubbleSort4比较次数33

    冒泡排序法的特点:

    时间复杂度:O(n^2)

    空间复杂度:O(1)

    稳定性:稳定

  • 相关阅读:
    AtomicLong与LongAdder的区别
    记录Vmware Workstation及Centos6.8 的安装
    java.lang.NoSuchMethodError问题处理
    java读取UTF-8的txt文件发现开头的一个字符问题
    Java多线程之内存可见性和原子性:Synchronized和Volatile的比较
    关于怎么解决java.lang.NoClassDefFoundError错误
    使用SFTP工具相关问题
    resin中关于url rewrite来传递jsessionid的问题
    Linux常用命令
    Jenkins简单安装及配置(Windows环境)
  • 原文地址:https://www.cnblogs.com/xsyfl/p/6892568.html
Copyright © 2011-2022 走看看