数据结构与算法——选择排序

原文链接:https://jiang-hao.com/articles/2020/algorithms-algorithms-selection-sort.html

排序思想

首先,找到数组中最小的那个元素,其次,将它和数组的第一个元素交换位置(如果第一个元素就是最小元素那么它就和自己交换)。其次,在剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。如此往复,直到将整个数组排序。这种方法我们称之为选择排序。选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。

img

那如何选出最小的一个元素呢?

很容易想到:先随便选一个元素假设它为最小的元素(默认为无序区间第一个元素),然后让这个元素与无序区间中的每一个元素进行比较,如果遇到比自己小的元素,那更新最小值下标,直到把无序区间遍历完,那最后的最小值就是这个无序区间的最小值。

算法性能

选择排序是不稳定的排序方法。

时间复杂度

选择排序的交换操作介于 0 和 (n - 1)次之间。选择排序的比较操作为 n(n - 1)/2 次。选择排序的赋值操作介于 0 和 3(n - 1) 次之间,1次交换对应三次赋值。

比较次数O(n^2) ,比较次数与关键字的初始状态无关,总的比较次数N=(n-1) + (n-2) + … +1 = n*(n-1)/2。

交换次数比冒泡排序少多了,由于交换所需CPU时间比比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快。选择排序每交换一对元素,它们当中至少有一个将被移到其最终位置上,因此对n个元素的表进行排序总共进行至多(n-1)次交换。在所有的完全依靠交换去移动元素的排序方法中,选择排序属于非常好的一种。

最好时间复杂度:最好情况是输入序列已经升序排列,需要比较n*(n-1)/2次,但不需要交换元素,即交换次数为:0;所以最好时间复杂度为О(n²)。

最坏时间复杂度:最坏情况是输入序列是逆序的,则每一趟都需要交换。即需要比较n*(n-1)/2次,元素交换次数为:n-1次。所以最坏时间复杂度还是*О(n²)。

平均时间复杂度:О(n²)

空间复杂度:只用到一个临时变量,所以空间复杂度O(1)

原地操作几乎是选择排序的唯一优点,当空间复杂度要求较高时,可以考虑选择排序;选择排序实际适用的场合非常罕见。

稳定性

选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果一个元素比当前元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中两个5的相对前后顺序就被破坏了,所以选择排序是一个不稳定的排序算法。

代码实现

单向选择

单向选择的排序算法也就是最传统简单的选择排序。其Java实现如下:

public static int[] selection_sort_original(int[] nums) 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值