美文网首页
选择排序(Selection Sort)

选择排序(Selection Sort)

作者: 小波同学 | 来源:发表于2021-11-19 00:42 被阅读0次

一、算法概述

1.1 算法分类

十种常见排序算法可以分为两大类:

  • 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。

  • 非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。

1.2 算法复杂度

1.3 相关概念

  • 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
  • 不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。
  • 时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。
  • 空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数。

二、选择排序(Selection Sort)

选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

2.1 算法描述

n个记录的直接选择排序可经过n-1趟直接选择排序得到有序结果。具体算法描述如下:

  • 初始状态:无序区为R[1..n],有序区为空;
  • 第i趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为R[1..i-1]和R(i..n)。该趟排序从当前无序区中-选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]和R[i+1..n)分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区;
  • n-1趟结束,数组有序化了。

2.2 动图演示

Selection Sort

2.3 排序过程

下面以数列{20,40,30,10,60,50}为例,演示它的选择排序过程(如下图)。


排序流程

  • 第1趟:i=0。找出a[1...5]中的最小值a[3]=10,然后将a[0]和a[3]互换。 数列变化:20,40,30,10,60,50 -- > 10,40,30,20,60,50
  • 第2趟:i=1。找出a[2...5]中的最小值a[3]=20,然后将a[1]和a[3]互换。 数列变化:10,40,30,20,60,50 -- > 10,20,30,40,60,50
  • 第3趟:i=2。找出a[3...5]中的最小值,由于该最小值大于a[2],该趟不做任何处理。
  • 第4趟:i=3。找出a[4...5]中的最小值,由于该最小值大于a[3],该趟不做任何处理。
  • 第5趟:i=4。交换a[4]和a[5]的数据。 数列变化:10,20,30,40,60,50 -- > 10,20,30,40,50,60

2.4 代码实现

/**
 * @author: huangyibo
 * @Date: 2021/11/17 16:17
 * @Description: 选择排序
 * 文字描述(以升序为例)
 * 1、将数组分为两个子集, 排序的和未排序的, 每一轮从未排序的子集中选出最小的元素, 放入排序子集
 * 2、重复以上步骤, 直到整个数组有序
 *
 * 优化方式:
 * 1、为减少交换次数, 每一轮可以先找最小的索引, 在每一轮最后交换元素
 *
 * 与冒泡排序比较:
 * 1、二者平均时间复杂度都是O(n²)
 * 2、选择排序一般都要快于冒泡, 因为其交换次数少
 * 3、但如果集合有序度高, 冒泡优于选择
 * 4、冒泡属于稳定排序算法, 而选择属于不稳定排序算法
 */
public class SelectionSort {

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

        selectionSort(arr);
        System.out.println(Arrays.toString(arr));
    }

    public static void selectionSort(int[] arr) {
        //i代表每轮选择最小元素要交换到的目标索引
        for (int i = 0; i < arr.length - 1; i++) {
            //代表最小元素的索引
            int minIndex = i;
            for (int j = minIndex + 1; j < arr.length; j++) {
                if(arr[minIndex] > arr[j]){
                    minIndex = j;
                }
            }
            //在每一轮最后交换元素
            if(minIndex != i){
                swap(arr, i, minIndex);
            }
        }
    }

    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

2.5 算法分析

表现最稳定的排序算法之一,因为无论什么数据进去都是O(n²)的时间复杂度,所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。理论上讲,选择排序可能也是平时排序一般人想到的最多的排序方法了吧。

2.6 与冒泡排序比较

  • 1、二者平均时间复杂度都是O(n²)
  • 2、选择排序一般都要快于冒泡, 因为其交换次数少
  • 3、但如果集合有序度高, 冒泡优于选择
  • 4、冒泡属于稳定排序算法, 而选择属于不稳定排序算法

参考:
https://www.cnblogs.com/onepixel/articles/7674659.html

https://www.cnblogs.com/skywang12345/p/3597641.html

相关文章

网友评论

      本文标题:选择排序(Selection Sort)

      本文链接:https://www.haomeiwen.com/subject/gyfjtrtx.html