2021 后端笔试准备 18 选择排序

选择排序是一个非常经典的排序算法在之前也详细的讲过了,今天单独提出来再讲一次:

插入排序算法基本思路

遍历输入的整数数组中的未排序的元素,找到其中最小的值,和已经排序被排序的元素右边的一个元素进行交换进行交换。

举个例子:

例如我们现在有输入数组[4, 3, 2, 1]我们需要把他排序成[1, 2, 3, 4],因此我们现在要找到输入数组中最小的元素,也就是1,然后将它和4交换,然后找到剩下数组中最小的元素,也就是2,然后和3交换,以此类推。最后我们就会得到[1, 2, 3, 4]。

知道了基本思路,让我们来看看他的时间复杂度和空间复杂度。

时间复杂度:

在排序第一个数的时候我们需要在数组中 0 ~ n - 1的范围上寻找到最小值,然后和0交换。

在排序第二个数的时候我们需要在数组中 1 ~ n - 1的范围上寻找到最小值,然后和1交换。

....

在排序第二个数的时候我们需要在数组中 n - 2 ~ n - 1的范围上寻找到最小值,然后和n - 1交换。

因此我们不难发现总的时间复杂度是 (n-1) + (n-2) + (n -3) ... [n-(n-2)],所以很明显这个是一个等差数列的加和,根据等差数列求和公式S = An^2 + Bn,我们可以得出他的时间复杂度是O(n^2+n),因此我们取最高项就是O(n^2)

空间复杂度:

空间复杂度是O(1),我们只需要两个变量来储存交换双方的下标,所以我们只需要存储额外的两个下标的值就行了,所以空间复杂度是O(1)

接下来我们来看代码:

public class Code01_SelectionSort {

    public static void selection(int[] arr){
        // 输入整数类型的列表
        if(arr == null || arr.length < 2){
            // 如果输入的数组为空或者小于 2就直接返回,为空和为1都不用排序是吧?
            return;
        }

        for(int i = 0; i < arr.length; i++) {
            //遍历数组中的每一个元素,申请一个变量记录最小的元素
            int minIdx = i;
            for(int j = i + 1; j < arr.length; j++){
                // 找到最小元素,交换
                minIdx = arr[i] < arr[minIdx] ? j : minIdx;
            }
            swap(arr, minIdx, i);
        }
    }

    public static void swap(int[] arr, int idxOne, int idxTwo){
        // 交换两个元素
        int temp = arr[idxOne];
        arr[idxOne] = arr[idxTwo];
        arr[idxTwo] = temp;
    }
}

Reference: https://italk.mashibing.com/course/detail/cour_00004003

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容