java选择排序优化

本文介绍了选择排序的工作原理,即每次从待排序元素中选出最小或最大元素放到已排序序列的末尾,直至排序完成。虽然选择排序的时间复杂度为O(n²),空间复杂度为O(1),但其稳定性较差。文中还分享了选择排序的算法实现,并提出了优化版的选择排序算法结果。
摘要由CSDN通过智能技术生成

选择排序工作原理:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。
时间复杂度:O(n²)
空间复杂度:O(1)
稳定性:不稳定。
算法如下:

import java.util.Arrays;
import java.util.Random;

/**
 * @hla
 * 最简单的选择排序
 */
public class SelectionSort {
    public static void main(String[] args) {
        Random r = new Random();
        int arr[] = new int[100000];
        long count = 0;
        //随机复制10万个整数
        for(int i=0;i<arr.length;i++){
            arr[i] = r.nextInt(100000);
        }
        //复制一份随机数以验证算法正确与否
        int[] arrcopy = new int[arr.length];
        System.arraycopy(arr,0,arrcopy,0,arr.length);
        //计算算法开始时间
        long startStamp = System.currentTimeMillis();
        //算法开始
        for(int j=0;j<arr.length-1;j++) {
            int minPos = j;
            for (int i = j+1; i < arr.length; i++) {
                if (arr[i] < arr[minPos]) {
                    minPos = i;
                }
                count++;
            }
            int temp = arr[minPos];
            arr[minPos] = arr[j];
            arr[j] = temp;
        }
        //计算算法结束时间
        long endStamp = System.currentTimeMillis();
        
        System.out.println("用时总长:"+(endStamp-startStamp));
        System.out.println("循环次数:"+count);
        //利用jdk自带的方法排序
        Arrays.sort(arrcopy);
        boolean same = true;
        for(int i = 0;i<arrcopy.length;i++){
            if(arr[i]!=arrcopy[i]) {
                same = false;
                System.out.println(arr[i]+" "+arrcopy[i]);
            }
        }
        System.out.println(same==true?"算法正确":"算法错误");
    }
}

结果:

用时总长:11253
循环次数:4999950000
算法正确

优化版如下:


import java.util.Arrays;
import java.util.Random;
/**
 * @hla
 **/
/**
 * 优化版:
 * 每次排序时找出最大值和最小值,最大值往右边放,最小值往左边放。
 */
public class SelectionSort2 {
    public static void main(String[] args) {
        Random r = new Random();
        int arr[] = new int[100000];
     for(int i=0;i<arr.length;i++){
           arr[i] =r.nextInt(100000);
       }
     //复制一份随机数组以便下面验证算法正确性
        int[] arrcopy = new int[arr.length];
       System.arraycopy(arr,0,arrcopy,0,arr.length);

        int ArrLength = (arr.length/2);
        int  temp1,temp2;
        long count = 0;
        //记录开始时间
        long startStamp = System.currentTimeMillis();
        //算法开始
    for(int j=0;j<ArrLength;j++){
        int minPos = j;
        int maxPos = j;
        for(int i=j;i<arr.length-j;i++){
                if (arr[minPos] > arr[i]) {
                    minPos = i;
                }
                if (arr[maxPos] < arr[i]) {
                    maxPos = i;
                }
                count++;
        }
         temp1  = arr[minPos];
                 arr[minPos] = arr[j];
                 arr[j] = temp1;
                   /**
                  这个判断是为了:
                  例如9 8 5 1 3 2 数组。当上面互换语句执行后
                  就变成了1 8 5 9 3 2数组。这时maxPos的位置不再是原本的位置了。
                  而是再互换后的minPos的位置上
                  **/
               if(j!=maxPos) {	//maxPos不能再原本的minPos位置上
                   temp2 = arr[maxPos];
                   arr[maxPos] = arr[arr.length - j - 1];
                   arr[arr.length - j - 1] = temp2;
               }else{
                   temp2 = arr[minPos];
                   arr[minPos] = arr[arr.length - j - 1];
                   arr[arr.length - j - 1] = temp2;
               }
    }
    //计算算法结束时间
    long endStamp = System.currentTimeMillis();
        System.out.println("用时总长:"+(endStamp-startStamp));
        System.out.println("循环次数:"+count);
        //验证该算法是否正确。
      Arrays.sort(arrcopy);
      boolean same = true;
      for(int i = 0;i<arrcopy.length;i++){
          if(arr[i]!=arrcopy[i]) {
              same = false;
              System.out.println(arr[i]+" "+arrcopy[i]);
          }
      }
        System.out.println(same==true?"算法正确":"算法错误");
    }
}

结果

用时总长:6839
循环次数:2500050000
算法正确

如果哪里有错,希望指出!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值