• 选择排序及改进


    选择排序

    基本思想

    冒泡排序中有一个缺点,比如,我们比较第一个数a1与第二个数a2的时候,只要a1比a2大就会交换位置,但是我们并不能确定a2是最小的元素,假如后面还有比它更小的,该元素还会与a2再次进行交换,而且这种交换有可能发生多次才能确定a2的最终位置。

    选择排序可以避免这种耗费时间的交换操作,从第一个元素开始,扫描整个待排数组,找到最小的元素放之后再与第一个元素交换位置,然后再从第二个元素开始,继续寻找最小的元素与第二个元素交换位置,依次类推。

    java实现

    1. //选择排序  
    2.    public void selectionSort(){  
    3.        int minPoint;  //存储最小元素的小标  
    4.        int len = array.length;  
    5.        int temp;  
    6.        int counter = 1;  
    7.         
    8.        for(int i=0;i<len-1;i++){  
    9.            
    10.           minPoint= i;   
    11.           for(int j=i+1;j<=len-1;j++){  //每完成一轮排序,就确定了一个相对最小元素,下一轮排序只对后面的元素排序  
    12.               if(array[j]<array[minPoint]){  //如果待排数组中的某个元素比当前元素小,minPoint指向该元素的下标  
    13.                  minPoint= j;  
    14.               }  
    15.           }  
    16.            
    17.           if(minPoint!=i){  //如果发现了更小的元素,交换位置  
    18.               temp= array[i];  
    19.               array[i]= array[minPoint];  
    20.               array[minPoint]= temp;  
    21.           }  
    22.            
    23.           System.out.print("第"+counter+"轮排序结果:");  
    24.           display();  
    25.           counter++;  
    26.        }  
    27.    }  
    //选择排序
       public void selectionSort(){
           int minPoint;  //存储最小元素的小标
           int len = array.length;
           int temp;
           int counter = 1;
          
           for(int i=0;i<len-1;i++){
             
              minPoint= i; 
              for(int j=i+1;j<=len-1;j++){  //每完成一轮排序,就确定了一个相对最小元素,下一轮排序只对后面的元素排序
                  if(array[j]<array[minPoint]){  //如果待排数组中的某个元素比当前元素小,minPoint指向该元素的下标
                     minPoint= j;
                  }
              }
             
              if(minPoint!=i){  //如果发现了更小的元素,交换位置
                  temp= array[i];
                  array[i]= array[minPoint];
                  array[minPoint]= temp;
              }
             
              System.out.print("第"+counter+"轮排序结果:");
              display();
              counter++;
           }
       }

    算法分析

    选择排序与冒泡排序一样,需要进行N*(N-1)/2次比较,但是只需要N次交换,当N很大时,交换次数的时间影响力更大,所以选择排序的时间复杂度为O(N2)

    虽然选择排序与冒泡排序在时间复杂度属于同一量级,但是毫无疑问选择排序的效率更高,因为它的交换操作次数更少,而且在交换操作比比较操作的时间级大得多时,选择排序的速度是相当快的。

    选择排序的改进

    传统的选择排序每次只确定最小值,根据改进冒泡算法的经验,我们可以对排序算法进行如下改进:每趟排序确定两个最值——最大值与最小值,这样就可以将排序趟数缩减一半。

    改进后的代码如下:

    1. //选择排序改进版  
    2.    public void selectionSort_improvement(){  
    3.        int minPoint;  //存储最小元素的小标  
    4.        int maxPoint;  //存储最大元素的小标  
    5.        int len = array.length;  
    6.        int temp;  
    7.        int counter = 1;  
    8.         
    9.        for(int i=0;i<len/2;i++){  
    10.            
    11.           minPoint= i;  
    12.           maxPoint= i;  
    13.           for(int j=i+1;j<=len-1-i;j++){  //每完成一轮排序,就确定了两个最值,下一轮排序时比较范围减少两个元素  
    14.               if(array[j]<array[minPoint]){  //如果待排数组中的某个元素比当前元素小,minPoint指向该元素的下标  
    15.                  minPoint= j;  
    16.                  continue;  
    17.               }else if(array[j]>array[maxPoint]){  //如果待排数组中的某个元素比当前元素大,maxPoint指向该元素的下标  
    18.                  maxPoint= j;  
    19.               }  
    20.           }  
    21.            
    22.           if(minPoint!=i){  //如果发现了更小的元素,与第一个元素交换位置  
    23.               temp= array[i];  
    24.               array[i]= array[minPoint];  
    25.               array[minPoint]= temp;  
    26.                
    27.               //原来的第一个元素已经与下标为minPoint的元素交换了位置  
    28.               //如果之前maxPoint指向的是第一个元素,那么需要将maxPoint重新指向array[minPoint]  
    29.               //因为现在array[minPoint]存放的才是之前第一个元素中的数据  
    30.               if(maxPoint== i){  
    31.                  maxPoint= minPoint;  
    32.               }  
    33.                
    34.           }  
    35.    
    36.           if(maxPoint!=len-1-i){  //如果发现了更大的元素,与最后一个元素交换位置  
    37.               temp= array[len-1-i];  
    38.               array[len-1-i]= array[maxPoint];  
    39.               array[maxPoint]= temp;  
    40.           }  
    41.            
    42.           System.out.print("第"+counter+"轮排序结果:");  
    43.           display();  
    44.           counter++;  
    45.        }  
    46.    }  
    //选择排序改进版
       public void selectionSort_improvement(){
           int minPoint;  //存储最小元素的小标
           int maxPoint;  //存储最大元素的小标
           int len = array.length;
           int temp;
           int counter = 1;
          
           for(int i=0;i<len/2;i++){
             
              minPoint= i;
              maxPoint= i;
              for(int j=i+1;j<=len-1-i;j++){  //每完成一轮排序,就确定了两个最值,下一轮排序时比较范围减少两个元素
                  if(array[j]<array[minPoint]){  //如果待排数组中的某个元素比当前元素小,minPoint指向该元素的下标
                     minPoint= j;
                     continue;
                  }else if(array[j]>array[maxPoint]){  //如果待排数组中的某个元素比当前元素大,maxPoint指向该元素的下标
                     maxPoint= j;
                  }
              }
             
              if(minPoint!=i){  //如果发现了更小的元素,与第一个元素交换位置
                  temp= array[i];
                  array[i]= array[minPoint];
                  array[minPoint]= temp;
                 
                  //原来的第一个元素已经与下标为minPoint的元素交换了位置
                  //如果之前maxPoint指向的是第一个元素,那么需要将maxPoint重新指向array[minPoint]
                  //因为现在array[minPoint]存放的才是之前第一个元素中的数据
                  if(maxPoint== i){
                     maxPoint= minPoint;
                  }
                 
              }
     
              if(maxPoint!=len-1-i){  //如果发现了更大的元素,与最后一个元素交换位置
                  temp= array[len-1-i];
                  array[len-1-i]= array[maxPoint];
                  array[maxPoint]= temp;
              }
             
              System.out.print("第"+counter+"轮排序结果:");
              display();
              counter++;
           }
       }
  • 相关阅读:
    poj 1286 Necklace of Beads 置换群polya计数
    linux下挂载(mount)光盘镜像文件移动硬盘
    union&enum的用法
    JNI编程
    hsqldb in Eucalyptus
    define宏定义
    Diskpart , WinPE
    (WCF)示例一: 构建一个简单的WCF Service: MagicEightBall
    Bill Gates 2007年哈佛演讲(中/英文)
    关于建立个人小网站的思考
  • 原文地址:https://www.cnblogs.com/mark-meng/p/6045862.html
Copyright © 2020-2023  润新知