选择排序

时间:2022-07-24
本文章向大家介绍选择排序,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

前面我们探讨了冒泡排序,今天我们接着讲讲选择排序,其实跟冒泡有点像的,但概念上不一样,童鞋,你听我慢慢跟你说。

什么是选择排序?

引言

最近看了一则寓言故事跟童鞋们分享一下,讲的是大山深处的神坑(为了激发大家的想象力,这里我就不画画了,请同学们自行脑补)。事情是这样子的,旁白站在上帝视角抛出一个上帝之问?为什么穷人努力工作还是越来越穷,生活不见起色,而富人却越来越富。一天,他们一同去爬山,这里我们先不考虑“推下去”这个梗,毕竟张东升他没去。当他们快到达山顶的时候,穷人看见前面的大坑,发现自己迈不过去,于是他找来了推车,一车子一车子地推石头子,打算把它填满,推的精疲力竭啊,一不小心脚绊倒了石头,连车带石头都掉进了神坑,这个时候他很苦恼,家里还有老还有小,我要努力我不能放弃啊,于是他又用双手搬石头一块一块地去填。此时,富人推着一个圆滚滚的巨石,将它推入坑中,因为直径比坑大,所有刚好卡在了上面,富人巧妙地通过了神坑。这个故事告诉我们,努力是没有错的,它也很重要,当你努力到一定程度就会由量变引起质变,但很多时候啊,选择大于努力。我们的一生会遇到很多的苦难和险阻,有坑在所难免,面对前方的未知,谁不怕呀!关键是我们要怎样去做好选择,走好每一步,这就引出了我们今天的话题“选择排序”。

定义

上面的故事,穷人和富人做的选择不一样,穷人做了很多次选择,选的都是比坑小的石头,而富人有其得道的见解,选了一块巨石去把坑给堵住了。再理解这个选择以后呢,我们再进一步做个游戏。

结合上面选择的案例思想,给定五块随机排列的石头,请你想一种办法,让他们由小到大排列。

我们是不是可以这样子去做,第一次,我找出了最小的那块石头,我把它和第一个位置的选手交换位置,第二次,我从第二个位置开始找一块最小的石头,找到后和第二个位置交换一下,以此类推,这个问题是不是就解决了啊。

所有,我们给出一个定义,给定一组数据集,对这组数据集进行遍历、每次从对应下标开始往后遍历找出最小的那位,将其与最开始的下标所在元素进行交换位置,形如这样的排序,我们将其称为“选择排序”。

实现一个选择排序

思路: 我们可以先假定那个min为最开始的那个元素,然后记录其下表进行遍历,当找到最小的那个元素之后,我们把min假定为最小元素后面那个,然后更新下标,以此类推,所以其平均复杂度是O(n^2)

code:

export default (arr) => {
  let min = arr[0];
  let idx = 0;
  for (let i = 0; i < arr.length - 1; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (min > arr[j]) {
        min = arr[j];
        idx = j;
      }
    }
    [arr[i], arr[idx]] = [min, arr[i]];
    [min, idx] = [arr[i + 1], i + 1];
  }
  return arr;
}

test:

这里笔者准备了几个测试用例,测试都通过了,这个排序应该没啥问题。

test case:

import selectSort from '../src/select';

test('select sort: test case 1', () => {
  expect(selectSort([2, 4, 3, 1])).toEqual([1, 2, 3, 4]);
});

test('select sort: test case 2', () => {
  expect(selectSort([2, 0, 2, 0])).toEqual([0, 0, 2, 2]);
});

test('select sort: test case 3', () => {
  expect(selectSort([1, 9, 9, 7])).toEqual([1, 7, 9, 9]);
});

test('select sort: test case 4', () => {
  expect(selectSort([0, 6, 1, 3])).toEqual([0, 1, 3, 6]);
});

test result:

PS E:documentreposJavaScript-Tsukukicodesort-study> npm run test:select

> sort-study@1.0.0 test:select E:documentreposJavaScript-Tsukukicodesort-study
> jest test/select.test.js

 PASS  test/select.test.js
  √ select sort: test case 1 (15 ms)
  √ select sort: test case 2
  √ select sort: test case 3
  √ select sort: test case 4

Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        7.013 s
Ran all test suites matching /test\select.test.js/i.
PS E:documentreposJavaScript-Tsukukicodesort-study>

emmm, 这里我是测试和开发分开写的,有兴趣可以阅读我之前写的jest的使用https://www.cnblogs.com/cnroadbridge/p/13524099.html

优化选择排序

跟之前讲的冒泡排序一次冒两个泡泡一个道理,你一次选择两个,一个最大一个最小,最大的与最后一个元素换位置,最小的与最前面的换位置,一个道理,有兴趣的童鞋自己实践下。

最后

本文选自Javascript筑基专题,项目地址:https://github.com/ataola/JavaScript-Tsukuki