首页 > 其他分享 >选择排序(Selection Sort)

选择排序(Selection Sort)

时间:2023-02-01 17:32:49浏览次数:49  
标签:Sort minIndex arr Selection int 元素 算法 排序

一、算法概述

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 泛型方式实现

public class SelectionSort {

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

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

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

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

2.6 算法分析

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

2.7 与冒泡排序比较

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

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

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

标签:Sort,minIndex,arr,Selection,int,元素,算法,排序
From: https://blog.51cto.com/u_14014612/6031706

相关文章

  • 插入排序(Insertion Sort)
    一、算法概述1.1算法分类十种常见排序算法可以分为两大类:比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排......
  • 十大经典排序算法
    0、算法概述0.1算法分类十种常见排序算法可以分为两大类:比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序......
  • 使用java python 实现 QI-页面排序-骑马钉
    链接:http://www.cnprint.org/bbs/thread/77/339531/......
  • 排序算法之希尔排序
    插入排序存在的问题:数组arr={2,3,4,5,6,1},这时需要插入的数是1,那么就要逐个将其他元素往后移,再把1放在首位。当需要插入的数是较小的数时,后移的次数明显增多,对效率很......
  • 剑指offer——Day17 排序(中等)
    Day172023.2.1排序(中等)40.最小的k个数自己实现直接用了排序的函数,这个没啥好说的代码表现没有进行优化,中规中矩41.数据流中的中位数自己实现自己尝试用了最朴......
  • 【八大数据排序法】选择排序法的图形理解和案例实现 | C++
    第十五章选择排序法:::hljs-center目录第十五章选择排序法●前言●认识排序●一、选择排序法是什么?1.简要介绍2.图形理解3.算法分析●二、案例实现1.......
  • (转)Golang sort包排序(详细全集)
    原文:https://blog.csdn.net/qq_43279457/article/details/121730095一、整型首先用下里面提供的最简单的例子,排序一下整形packagemainimport( "fmt" "sort")funcmai......
  • aijs 对象排序
    1.字典对象functiondictGetValue(value){for(dictGetValueIndexinvalue)returnvalue[dictGetValueIndex]}functiondictGetKey(value){for(dictGetKeyInd......
  • java 排序
    ......
  • 23. Merge k Sorted Lists[Hard]
    23.MergekSortedListsYouaregivenanarrayofklinked-listslists,eachlinked-listissortedinascendingorder.Mergeallthelinked-listsintoonesor......