八大排序算法--选择排序(动图理解)

选择排序

算法思路

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

选择排序的步骤:

1>首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

2>再从剩余未排序元素中继续寻找最小(大)元素,然后放到未排序序列的起始位置。

3>重复第二步,直到所有元素均排序完毕。

动画演示

算法代码

java 复制代码
public static void selectSort1(int[] a){

        for (int i = 0; i < a.length; i++) {
            int minIndex = i;
            for (int j = i+1 ; j <a.length ; j++) {
                if(a[j] <= a[minIndex]){
                    minIndex = j;
                }
            }
            if(minIndex == i) continue;  //说明没找到更小的
            int tmp = a[minIndex];
            a[minIndex] = a[i];
            a[i] = tmp;
        }
    }

复杂度分析

时间复杂度 O(n^2) 等差数列

空间复杂度 O(1)

稳定性 不稳定

选择排序优化

选择排序的优化思路一般是在一趟遍历中,同时找出最大值与最小值,放到数组两端,这样就能将遍历的趟数减少一半。第一次选择最大值与最小值,过程如下:

算法代码

java 复制代码
public static void selectSort2(int[] a){

        int left  = 0;
        int right = a.length-1;
        while(left<right) {
            int minIndex = left;
            int maxIndex = right;
            for(int i = left+1;i<=right;i++) {
                if(a[i] < a[minIndex]) {
                    minIndex = i;
                }
                if(a[i] > maxIndex) {
                    maxIndex = i;
                }
            }

            //交换左边
            int tmp1 = a[minIndex];
            a[minIndex] = a[left];
            a[left] = tmp1;

            if(maxIndex == left) {   //很重要的一点细节
                maxIndex = minIndex;
            }

            //交换右边
            int tmp2 = a[maxIndex];
            a[maxIndex] = a[right];
            a[right] = tmp2;

            left++;
            right--;

        }
    }

时间复杂度测试

接下来我们试着用大量数据测试一下。

int[] a = new int[10_0000]; //10万个数据测试

1.orderArray函数实现生成一个基本有序数列,即从小到大排列。

java 复制代码
public static void orderArray(int[] a) {
        for (int i = 0; i < a.length; i++) {
            a[i] = i;
        }
 }

2.notOrderArray函数生成一个倒序数列,即从大到小排列。

java 复制代码
public static void notOrderArray(int[] a) {
        for (int i = 0; i < a.length; i++) {
            a[i] = a.length-i;
        } 
}

3.randomArray函数生成一个随机无序数列。

java 复制代码
 public static void randomArray(int[] a) {
        Random random = new Random();
        for (int i = 0; i < a.length; i++) {
            a[i] = random.nextInt(10_0000);
        }
 }

4.testInsertSort函数测试 System.currentTimeMillis() 返回值单位是毫秒。

java 复制代码
 public static void testInsertSort(int[] a){
        int[] tmpArray = Arrays.copyOf(a,a.length);
        long startTime = System.currentTimeMillis();    //注意用long接收
        shellSort(tmpArray);
        long endTime = System.currentTimeMillis();  //返回单位是毫秒
        System.out.println("选择排序耗时:"+(endTime-startTime));
  }

5.main函数调用执行

java 复制代码
public static void main(String[] args) {
 
        int[] a = new int[10_0000];
        //有序
        System.out.println("基本有序数列");
        orderArray(a);
        testInsertSort(a);
 
        //倒序
        System.out.println("逆序数列");
        notOrderArray(a);
        testInsertSort(a);
 
        //随机乱序
        System.out.println("无序数列");
        randomArray(a);
        testInsertSort(a);
}

测试结果

从结果来看,对于大量的数据,优化后的反而更慢了,应该是这种排序算法更适合少量数据。

我们放250个数据进行测试。

结果证明耗时上还是有所下降的。

完整代码

java 复制代码
import java.util.Random;


public class sort {
    public static void main(String[] args) {
    
        int[] a = new int[10_0000];
        //有序
        System.out.println("基本有序数列");
        orderArray(a);
        testInsertSort(a);

        //无序
        System.out.println("逆序数列");
        notOrderArray(a);
        testInsertSort(a);

        //乱序
        System.out.println("无序数列");
        randomArray(a);
        testInsertSort(a);

    }

    public static void selectSort(int[] a){

        for (int i = 0; i < a.length; i++) {
            int minIndex = i;
            for (int j = i+1 ; j <a.length ; j++) {
                if(a[j] <= a[minIndex]){
                    minIndex = j;
                }
            }
            if(minIndex == i) continue;  //说明没找到更小的
            int tmp = a[minIndex];
            a[minIndex] = a[i];
            a[i] = tmp;
        }
   }


    //生成有序数组  从小到大排列
    public static void orderArray(int[] a) {
        for (int i = 0; i < a.length; i++) {
            a[i] = i;
        }
    }

    //n无序 其实就是从大到小排列
    public static void notOrderArray(int[] a) {
        for (int i = 0; i < a.length; i++) {
            a[i] = a.length-i;
        }
    }

    //乱序 随机生成序列
    public static void randomArray(int[] a) {
        Random random = new Random();
        for (int i = 0; i < a.length; i++) {
            a[i] = random.nextInt(10_0000);
        }
    }

    //大量数据测试
    public static void testInsertSort(int[] a){
        int[] tmpArray = Arrays.copyOf(a,a.length);
        long startTime = System.currentTimeMillis();    //注意用long接收
        selectSort(tmpArray);
        long endTime = System.currentTimeMillis();
        System.out.println("选择排序耗时:"+(endTime-startTime));
    }
}

创作不易,如果本篇博客对您有一定的帮助,大家记得留言+点赞哦。

相关推荐
ghie909012 分钟前
基于MATLAB的遗传算法优化支持向量机实现
算法·支持向量机·matlab
CryptoRzz17 分钟前
欧美(美股、加拿大股票、墨西哥股票)股票数据接口文档
java·服务器·开发语言·数据库·区块链
杂货铺的小掌柜37 分钟前
apache poi excel 字体数量限制
java·excel·poi
大厂码农老A1 小时前
你打的日志,正在拖垮你的系统:从P4小白到P7专家都是怎么打日志的?
java·前端·后端
朝新_1 小时前
【优选算法】第一弹——双指针(上)
算法
艾菜籽1 小时前
Spring MVC入门补充2
java·spring·mvc
艾莉丝努力练剑1 小时前
【C++STL :stack && queue (一) 】STL:stack与queue全解析|深入使用(附高频算法题详解)
linux·开发语言·数据结构·c++·算法
爆更小哇1 小时前
统一功能处理
java·spring boot
程序员鱼皮1 小时前
我造了个程序员练兵场,专治技术焦虑症!
java·计算机·程序员·编程·自学
CoovallyAIHub1 小时前
ICLR 2026 惊现 SAM 3,匿名提交,实现“概念分割”,CV领域再迎颠覆性突破?
深度学习·算法·计算机视觉