排序算法:详解选择排序算法及其java实现

216 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情

作者平台:

| CSDN:blog.csdn.net/qq_4115394…

| 掘金:juejin.cn/user/651387…

| 知乎:www.zhihu.com/people/1024…

| GitHub:github.com/JiangXia-10…

| 微信公众号:1024笔记

本文一共1932字,预计阅读7分钟

前言

参加笔试或者面试的时候算法题基本是考验一个开发的最基本的考项之一了,算法中最基础的又是八大排序算法,之前的一篇文章介绍了八大排序算法中的冒泡排序,除了冒泡排序之外,选择排序也是使用较多的排序算法之一了,今天一起复习下选择排序算法。

什么是选择排序

选择排序(Selection sort)是八大排序算法中的一种,它也是一种比较简单直观的排序算法。它的逻辑就是:

根据排序时升序还是降序,第一次排序时从待排序的数据元素中选出最小(或最大)的一个元素,存放在数组的起始位置,如果存在则将第一个元素和最小元素的位置互换,然后后面的每次排序都是再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的最后。以此类推,直到全部待排序的数据元素的个数为零。

可以这么理解:队伍里有五个人,个子分别是170cm、150cm、164cm、154cm、145cm。

如果使用选择排序对这个队伍按照个子从低到高的顺序进行排序,那么就是:

第一次排序从队伍里找出个子最小的一个(145cm),并与目前队伍里的第一个(170cm)进行交换,那么第一次排序之后的结果就是:145、150、164、154、170

第二次排序就是从第二个位置开始到最后一个位置中选择个子最矮的一个(150),并与目前第二个位置上的人交换,那么第二次排序之后的结果就是:145、150、164、154、170

第三次排序就是从第三个位置开始到最后一个位置选择个子最矮的一个(154)并与目前第三个位置上的人交换,那么第三次排序之后的结果就是:145、150、154、164、170

第四次排序就是从第四个位置开始到最后一个位置选择个子最矮的一个(164)并与目前第四个位置上的认交换,这里不用,第四次排序之后的结果就是最后的排序结果145、150、154、164、170。

所以总共通过n-1次排序,得到一个按照一定升序或者降序的有序的队伍了。

但是很显然这是一个非稳定的排序方法。先来复习下稳定排序和非稳定排序。

稳定排序:排序前后两个相等的数相对位置不变,则算法稳定 非稳定排序:排序前后两个相等的数相对位置发生了变化,则算法不稳定

因为还是以排队为例,如果是一个三个人的队伍,个子分别是170(张三)、160(李四)、160(王五),如果要以升序排队,那么第一步就会把位置一和位置三的人互换,王五和李四的相对位置是李四在前,但是使用了选择排序之后,王五和李四的位置发生了变化,最终排序是:王五、李四、张三,李四在前了,所以是非稳定排序。

常见的排序算法中稳定排序算法有:

1、冒泡排序

2、插入排序

3、桶排序

4、计数排序

5、合并排序

6、基数排序

7、二叉排序树排序

非稳定排序算法有:

1、选择排序

2、希尔排序

3、组合排序

4、堆排序

5、快速排序

选择排序的java实现

使用java对选择排序进行模拟实现,具体代码如下:

public class SelectSort {

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

    }

    public static void Sort(int[] numbers){
        for (int i = 0; i < numbers.length-1; i++) {
            //最小下标
            int miniIndex = i;
            //最小值
            int mini = numbers[i];
            //遍历比较
            for (int j = i+1; j < numbers.length; j++) {
                if (mini > numbers[j]) {
                    miniIndex = j ;
                    mini = numbers[j ];
                }
            }
            if (miniIndex != i) {
                numbers[miniIndex] = numbers[i];
                numbers[i] = mini;
            }
            //输出每次排序结果
            System.out.println("第"+(i+1)+"次排序");
            System.out.println(Arrays.toString(numbers));
        }
    }
}

运行结果入下:

image.png

通过上述分析和代码分析,可以发现选择排序的最好和最差时间复杂度都是O(N²),所以平均时间复杂度也是O(N²)。

总结

选择排序原理就是每次从未排序的队伍中选择一个最小或者最大的元素放到已排序队伍中的队尾,并交换当前位置上元素和该次选择最小元素的位置,直到未排序队伍中仅剩一个元素,即为最大或最小的元素。需要交换的次数也是n-1次,所以最好、最差和平均时间复杂度都是O(N²),并且因为相等元素的相对位置会在经过排序后发生变化,所以它是不稳定排序。

其他推荐: