选择排序
前面我们探讨了冒泡排序,今天我们接着讲讲选择排序,其实跟冒泡有点像的,但概念上不一样,童鞋,你听我慢慢跟你说。
什么是选择排序?
引言
最近看了一则寓言故事跟童鞋们分享一下,讲的是大山深处的神坑(为了激发大家的想象力,这里我就不画画了,请同学们自行脑补)。事情是这样子的,旁白站在上帝视角抛出一个上帝之问?为什么穷人努力工作还是越来越穷,生活不见起色,而富人却越来越富。一天,他们一同去爬山,这里我们先不考虑“推下去”这个梗,毕竟张东升他没去。当他们快到达山顶的时候,穷人看见前面的大坑,发现自己迈不过去,于是他找来了推车,一车子一车子地推石头子,打算把它填满,推的精疲力竭啊,一不小心脚绊倒了石头,连车带石头都掉进了神坑,这个时候他很苦恼,家里还有老还有小,我要努力我不能放弃啊,于是他又用双手搬石头一块一块地去填。此时,富人推着一个圆滚滚的巨石,将它推入坑中,因为直径比坑大,所有刚好卡在了上面,富人巧妙地通过了神坑。这个故事告诉我们,努力是没有错的,它也很重要,当你努力到一定程度就会由量变引起质变,但很多时候啊,选择大于努力。我们的一生会遇到很多的苦难和险阻,有坑在所难免,面对前方的未知,谁不怕呀!关键是我们要怎样去做好选择,走好每一步,这就引出了我们今天的话题“选择排序”。
定义
上面的故事,穷人和富人做的选择不一样,穷人做了很多次选择,选的都是比坑小的石头,而富人有其得道的见解,选了一块巨石去把坑给堵住了。再理解这个选择以后呢,我们再进一步做个游戏。
结合上面选择的案例思想,给定五块随机排列的石头,请你想一种办法,让他们由小到大排列。
我们是不是可以这样子去做,第一次,我找出了最小的那块石头,我把它和第一个位置的选手交换位置,第二次,我从第二个位置开始找一块最小的石头,找到后和第二个位置交换一下,以此类推,这个问题是不是就解决了啊。
所有,我们给出一个定义,给定一组数据集,对这组数据集进行遍历、每次从对应下标开始往后遍历找出最小的那位,将其与最开始的下标所在元素进行交换位置,形如这样的排序,我们将其称为“选择排序”。
实现一个选择排序
思路: 我们可以先假定那个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
- RavenDb学习(八)高级特性上半部分
- 微信钱包中58到家首页为什么这么快
- hbase源码系列(二)HTable 探秘
- hbase源码系列(三)Client如何找到正确的Region Server
- hbase源码系列(五)Trie单词查找树
- 如何在特定的渗透测试中使用正确的Burp扩展插件
- hbase源码系列(十一)Put、Delete在服务端是如何处理?
- 大数据如何帮飞机节油?
- hbase源码系列(十二)Get、Scan在服务端是如何处理?
- OpenStack:建立虚拟的渗透测试实验环境 – 网络篇
- Kettle 添加对应hadoop版本的支持
- Layui常用方法
- 使用Identity Server 4建立Authorization Server (4)
- 使用Identity Server 4建立Authorization Server (3)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法