算法总结-直接选择排序

算法定义

直接选择排序是选择排序的一种,是一种简单的排序方法,根据百科的定义,它的基本思想是:第一次从R[0] ~ R[n - 1]中选取最小值,与R[0]交换,第二次从R[1] ~ R[n - 1]中选取最小值,与R[1]交换...第i次从R[i - 1] ~ R[n - 1]中选取最小值,与R[i - 1]交换...第n-1次从R[n - 2] ~ R[n - 1]中选取最小值,与R[n - 2]交换,总共通过n - 1次,得到一个按排序码从小到大排列的有序序列。

算法原理

直接选择排序算法的原理如下:

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

2、再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

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

直接选择排序动图

代码实现

按照上面的思路,代码如下:

public class Main {

    // 直接选择排序(选择排序),平均时间复杂度O(n^2),最好时间复杂度O(n^2),最坏时间复杂度O(n^2),空间复杂度O(1)
    public void directlySelectSort(int[] arr) {
        // 获取数组的长度
        int n = arr.length;

        // 走n-1趟,每趟确定当前的最小值
        for (int i = 0; i < n - 1; ++i) {
            // 定义当前的最小值下标
            int minIndex = i;

            // 最小值下标的值和后面的值逐个比较,找出这里的最小值下标
            for (int j = i + 1; j < n; ++j) {
                // 若当前下标的值比最小值下标的值还小,那么最小值下标设置为当前下标
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }

            if (minIndex != i) {
                // 若后面能找到比最小值下标的值更小的值,那么交换两个元素,否则最小值下标的值就是当前的最小值,无需交换元素
                arr[i] ^= arr[minIndex];
                arr[minIndex] ^= arr[i];
                arr[i] ^= arr[minIndex];
            }
        }
    }

}

算法效率

直接选择排序是不稳定的排序算法。

时间复杂度都是O(n²),因为无论数组是哪种情况,都需要进行两次for循环,都是确定数组前n-1个最小值,即使数组是本身有序的。

空间复杂度为O(1),因为只使用有限个数的变量。

算法稳定性的意思是:假如在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i] = r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。

例如:一堆商品,先按价格排序,再在价格排序好的基础上按销量排序,如果有两个商品的销量一样,那么按照常理,两个一样销量的商品就要按照原来价格的顺序去排列,也就是说有两个排序属性了,先按照销量排序,再按照价格排序,如果算法是稳定的,那么就是相同销量的商品还会按照原来价格的顺序来排,如果算法不是稳定的,那么可能相同销量的商品的顺序会变得不确定,简单来说就是,稳定算法就是数组中相等的值在排序后还是保持原来相对的顺序不变。

如果单纯就是按照一种属性的排序,那么算法是否稳定没有意义,但是现实生活中并不是都是按照单一属性来排序的,很多是按照多属性来排序的,所以算法是否稳定是很重要的一个指标。

直接选择排序,因为在每一次确定当前最小值时,有可能会破坏数组中相等的值的相对顺序,例如数组:[3, 3, 1],第一趟确定最小值后就变成[1, 3, 3],原数组中的两个2的相对顺序就被改变了,所以我们说直接选择排序是不稳定的。

平均时间复杂度:O(n^2)

最好时间复杂度:O(n^2)

最坏时间复杂度:O(n^2)

空间复杂度:O(1)

参考资料

直接选择排序动图来自:直接选择排序

原文链接

原文链接:算法总结-直接选择排序

你可能感兴趣的:(算法总结-直接选择排序)