java选择排序优化

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

选择排序工作原理:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。
时间复杂度: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
算法正确

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

### Java选择排序算法优化 #### 一、基本的选择排序实现 选择排序通过不断寻找未排序部分中的最小(或最大)元素并与当前索引位置交换,从而逐步构建有序序列。以下是标准的选择排序实现: ```java public class SelectionSort { public static void sort(int[] array) { int n = array.length; for (int i = 0; i < n - 1; i++) { int minIndex = i; for (int j = i + 1; j < n; j++) { if (array[j] < array[minIndex]) { minIndex = j; } } // 如果找到新的最小值,则交换 if (minIndex != i) { swap(array, i, minIndex); } } } private static void swap(int[] array, int i, int j) { int temp = array[i]; array[i] = array[j]; array[j] = temp; } } ``` #### 二、减少不必要的交换操作 在上述代码中,每次内层循环结束后都会执行一次`swap()`函数调用。实际上只有当确实找到了更小的数时才需要真正做这个动作。因此可以在发现新最小值的同时记录下来,在一轮遍历结束之后再决定是否要进行真正的交换。 改进后的版本如下所示[^3]: ```java public class OptimizedSelectionSort { public static void optimizedSort(int[] array) { int n = array.length; for (int i = 0; i < n - 1; i++) { int minIdx = i; for (int j = i + 1; j < n; j++) { if (array[j] < array[minIdx]) minIdx = j; } // 只有当存在较小数值时才会发生实际的数据移动 if (minIdx != i) swap(array, i, minIdx); } } private static void swap(int[] array, int a, int b) { final int tmp = array[a]; array[a] = array[b]; array[b] = tmp; } } ``` 即使进行了这样的优化选择排序的时间复杂度仍然保持为 O(n²),这使得它不适合处理非常大的数据集。对于大数据量的情况,建议采用其他更为高效的排序方式如快速排序或归并排序等.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值