• 排序算法(一)冒泡法


    1,排序算法的优劣评价标准

    稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面;

    不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面;

    时间复杂度: 一个算法执行所耗费的时间。

    空间复杂度: 运行完一个程序所需内存的大小。

    2,算法描述

    算法描述:它重复地走访过要排序的元素,依次比较相邻两个元素,如果他们的顺序错误就把他们调换过来,直到没有元素再需要交换,排序完成。

    3,实现步骤

    • 比较相邻的元素,如果前一个比后一个大,就把它们两个调换位置。
    • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
    • 针对所有的元素重复以上的步骤,除了最后一个。
    • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

      1)常规实现

     1 private static void bubbleSort1(int[] a){
     2     long start = System.nanoTime();    //该函数以纳秒计时,1毫秒=1000微秒=1000000纳秒
     3     int len = a.length;
     4     for(int i = 0; i < len; i++){      //需要n-1次循环, 每次最大元素就像气泡一样"浮"到数组的最后
     5         for(int j = 0; j < len - 1 -i; j++){// 依次比较相邻的两个元素,使较大的那个向后移
     6             if(a[j] > a[j+1]){         //如果条件改为a[j] >= a[j+1],则为不稳定排序
     7                 swap(a,j,j+1);                    
     8             }                
     9         }
    10     }
    11     long end = System.nanoTime();  
    12     System.out.println((end - start)/1000.0 + "us");
    13     }
    14 
    15 private static void swap(int[] a, int j, int i) {
    16     int temp = a[j];
    17     a[j] = a[i];
    18     a[i] = temp;        
    19 }

      2)改进实现

      分析常规实现的问题,它不管传入数组是否已经(部分)有序,都需要进行n-1次循环,每次循环里都要依次比较相邻元素。

      改进:设置一标志位pos,用于记录每趟排序中最后一次进行交换的位置。由于pos位置之后的记录均已交换到位,故在进行下一趟排序时只要扫描到pos位置即可。例如极端情况,一个有序数组进行排序,则只需要1次扫描即可。

      说明:改进只是对有序或部分有序的序列有效果,如果完全无序的序列排序,则没有效果。

     1 private static void bubbleSort2(int[] a) {
     2     long start = System.nanoTime();  
     3     int len = a.length;
     4     int i = len - 1;  //用于记录每趟排序中最后一次进行交换的位置,即下次扫描到这就OK了,后面的已经有序了
     5     while (i > 0) {   //i=0表示,从0位置往后的元素都有序了则停止扫描
     6         int pos = 0;  
     7         for (int j = 0; j < i; j++) {  
     8             if (a[j] > a[j + 1]) {  
     9                 pos = j;  
    10                 swap(a,j,j+1);      
    11             }  
    12         }  
    13         i = pos;  
    14     }  
    15     long end = System.nanoTime();  
    16     System.out.println((end - start)/1000.0 + "us");  
    17 }

    4,算法分析

    时间复杂度:

    最佳情况:T(n) = O(n) 当输入的数据已经是正序时

    最差情况:T(n) = O(n^2) 当输入的数据是反序时

    平均情况:T(n) = O(n^2)

    空间复杂度:

    在每次循环中,所需要的额外空间就是在进行数值交换时候的一个额外空间,所以空间复杂度为一个常量O(1)

    稳定性:稳定

    5,其他

    1)单链表实现冒泡排序

    2)改变判断条件即可实现基于不同特性的排序,上面是依据大小排序,还可以依据奇偶等。

    参考

    http://www.cnblogs.com/eniac12/p/5329396.html

  • 相关阅读:
    Android 序列化 反序列功能
    Android两个应用之间共享数据之SharedPrefence
    利用Asp.Net的Identity控制登录权限
    基元类型
    CLR概述
    python中的函数-基础
    较为复杂的sql
    oracle中的替换字段字符串的方法
    使用Sql查看表对应的外键关系。
    js中的除法
  • 原文地址:https://www.cnblogs.com/xdyixia/p/9136412.html
Copyright © 2020-2023  润新知