zoukankan      html  css  js  c++  java
  • 冒泡排序、选择排序、直接插入排序

    冒泡排序

    比较相邻的元素,如果第一个比第二个大,就交换他们。第一步所有相邻的排序做完后,最大的数字会在最右边,接着重复步骤。

    public class Main {

    public static void main(String[] args) {
    int[] array={9,5,2,6,1,3,8,4,10,7};
    for (int i=0;i<array.length;i++){
    for (int j=0;j<array.length-i-1;j++){
    if (array[j]>array[j+1]){
    int number=array[j];
    array[j]=array[j+1];
    array[j+1]=number;

    }

    }
    }

    for (int number:array){
    System.out.println(number);
    }
    }
    }

    控制台输出:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

     假设参与比较的数组元素个数为 N,则第一轮排序有 N-1 次比较,第二轮有 N-2 次,如此类推,这种序列的求和公式为:

    
    

      (N-1)+(N-2)+...+1 = N*(N-1)/2

        当 N 的值很大时,算法比较次数约为 N2/2次比较,忽略减1。

     假设数据是随机的,那么每次比较可能要交换位置,可能不会交换,假设概率为50%,那么交换次数为 N2/4。不过如果是最坏的情况,初始数据是逆序的,那么每次比较都要交换位置。

      交换和比较次数都和N2 成正比。由于常数不算大 O 表示法中,忽略 2 和 4,那么冒泡排序运行都需要 O(N2) 时间级别。

      其实无论何时,只要看见一个循环嵌套在另一个循环中,我们都可以怀疑这个算法的运行时间为 O(N2)级,外层循环执行 N 次,内层循环对每一次外层循环都执行N次(或者几分之N次)。这就意味着大约需要执行N2次某个基本操作。

     

     

    选择排序 

    选择排序是每一次从待排序的数据元素中选出最小的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。

    
    
    public class Main {

    public static void main(String[] args) {
    int[] array={9,5,2,6,1,3,8,4,10,7};
    for (int i=0;i<array.length-1;i++){
    int min=i;
    for (int j=i+1;j<array.length;j++){
    if (array[j]<array[i]) {
    min=j;
    if (i!=j){
    int number=array[i];
    array[i]=array[min];
    array[min]=number;
    }
    }
    }
    }

    for (int number:array){
    System.out.println(number);
    }
    }
    }
    
    
    控制台输出:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     

           选择排序和冒泡排序执行了相同次数的比较:N*(N-1)/2,但是至多只进行了N次交换。

    
    

      当 N 值很大时,比较次数是主要的,所以和冒泡排序一样,用大O表示是O(N2) 时间级别。但是由于选择排序交换的次数少,所以选择排序无疑是比冒泡排序快的。当 N 值较小时,如果交换时间比比较时间大的多,那么选择排序是相当快的。

     

    直接插入排序

    
    

    插入排序是每一步将一个待排序的记录,插入到前面已经排好序的有序序列中去,直到插完所有元素为止。

    
    
    public class Main {

    public static void main(String[] args) {
    int[] array = {9, 5, 2, 6, 1, 3, 8, 4, 10, 7};
    int j;

    for (int i=1;i<array.length;i++){
    int number=array[i];
    j=i;
    while (j>0&&number<array[j-1]){
    array[j]=array[j-1];
    j--;
    }
    array[j]=number;
    }


    for (int number : array) {
    System.out.println(number);
    }

    }
    }
    
    
    控制台输出:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10


     在第一轮排序中,它最多比较一次,第二轮最多比较两次,一次类推,第N轮,最多比较N-1次。因此有 1+2+3+...+N-1 = N*(N-1)/2。

      假设在每一轮排序发现插入点时,平均只有全体数据项的一半真的进行了比较,我们除以2得到:N*(N-1)/4。用大O表示法大致需要需要 O(N2) 时间级别。

      复制的次数大致等于比较的次数,但是一次复制与一次交换的时间耗时不同,所以相对于随机数据,插入排序比冒泡快一倍,比选择排序略快。

    这里需要注意的是,如果要进行逆序排列,那么每次比较和移动都会进行,这时候并不会比冒泡排序快。



  • 相关阅读:
    Vue 生命周期
    Vue
    对象
    【菜鸟学php】用菜鸟的眼光浅谈php上传文件
    在职程序猿为啥要考相关证书
    微信分享js失效,分享内容自定义将作为接口开放
    【菜鸟学Linux】gzip解压报错:gzip: stdin has more than one entry--rest ignored
    【菜鸟学php】在敲代码的路上,给自己点时间来思考
    【菜鸟学php】小菜鸟由帝国备份王在Wamp环境下打开500错误浅谈PHP程序员
    eclipse中使用ctrl无法追踪函数的问题(php项目)
  • 原文地址:https://www.cnblogs.com/neowu/p/10743419.html
Copyright © 2011-2022 走看看