排序算法(二)选择排序

153 阅读2分钟

本文首发于我的个人博客

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

选择排序的主要核心思想如下:

  • 对数组进行 n 轮遍历,每轮遍历时都比上一轮遍历的开始索引大一个数。比如上次是从0开始遍历。这次就从1开始遍历,下次从2开始,以此类推。
  • 每轮遍历时,不断地对每个数进行对比获取当前轮中最小的值,并存储最小的值的下标。
  • 每轮遍历结束后,对最小值下标与当前轮开始下标进行对比,如果下标不相等,则交换双方的值。之后进入下一轮遍历。
  • 重复第二、第三步直到遍历完n 轮。

虽然选择排序和冒泡排序有异曲同工之妙,它们的相同之处在于:

  • 如果都是倒序数组情况下,它们的时间复杂度都是 O(n2n^2)。
  • 都是进行了 n 轮遍历,每轮遍历时求最小/最大值,并放在头部/尾部。

但是它们也是有一定区别的:

  • 选择排序是每轮只交换一次,冒泡排序是每轮交换多次。
  • 如果数组是正序的情况下,冒泡排序只遍历一次,选择排序依旧要遍历n次。
  • 冒泡排序交换的是相邻的元素,选择排序则可以交换不相邻的元素。
  • 冒泡排序最好的情况下(正序),是O( n )。最坏的情况(倒序)是O( n2n^2 )。选择排序是不论哪种情况都是O( n2n^2 )。

Code

function sortArray(nums: number[]): number[] {
    for(let outIdx: number = 0; outIdx < nums.length; ++outIdx) {
        let minIdx: number = outIdx;
        let innerIdx: number = outIdx
        for (; innerIdx < nums.length; ++innerIdx) {
            if (nums[minIdx] > nums[innerIdx]){
                minIdx = innerIdx
            }
        }
        if (minIdx !== outIdx){
            let tmp:number = nums[minIdx];
            nums[minIdx] = nums[outIdx]
            nums[outIdx] = tmp
        }
    }
    return nums
};

复杂度分析

时间复杂度:O( n2n^2 )。

空间复杂度:O( 1 )。