算法之旅 | 选择排序法

HTML5学堂-码匠:数据快速的计算与排序,与前端页面性能有直接的关系。由于排序的算法有很多,在本次“算法系列”的分享当中,我们先从简单易上手的选择排序法开始,其它的排序算法会随后陆续跟大家一起分享。

算法的基本概念

算法是什么,它有何作用

为解决一个问题而采取的方法和步骤,称为算法。

我们可以把算法看成一本“福字剪纸教程”,其中每一种算法就是剪纸教程中的一种包含“固定步骤”的剪纸方法,使用者只要按照步骤进行剪纸,就可以剪出好看的福字。

之所以有这么多的算法,在于不同算法解决问题的效率各有不同,适合不同的场景。随着问题规模的增长,算法之间的差距会变的不可跨越。提升解决问题的效率,不仅仅依赖于选择快速的硬件,还依赖于选择有效(适合)的算法。

排序的使用场景

针对数组进行从大到小(或从小到大)的排序。例如:管理系统中按照成绩的排序,按阅读量对文章的排序等。

数据快速的计算与排序,与前端页面性能有直接的关系。(譬如在页面中有10000条的数据需要靠JS进行排序,采用不同的算法所消耗的时间差距甚大,直接影响着网站的用户体验)

常见的排序方法

较为常见的排序方法,包括:冒泡排序、选择排序、快速排序、二分法插入排序等。

由于排序的算法有很多,在本次“算法系列”的分享当中,我们先从简单易上手的选择排序法开始,其它的排序算法会随后陆续跟大家一起分享。

选择排序法的基本原理

先找到序列中最小的数,将它和序列中第一个数交换位置;

接下来,在剩下的序列中继续此操作:找到最小的数,将它和序列中的第二个数交换位置;

依此类推,直到将整个序列排序完成。

简言之,选择排序就是 —— 不断地选择剩余序列中的最小者,然后与未排序数列的“第一个”数字交换位置。

案例说明

如下数组中,黑色代表待排序,蓝色代表已排序;

初始状态:[9, 8, 3, 1, 2, 4]

第一次排序结果:[1, 8, 3, 9, 2, 4] 在剩余的序列中最小的数1,与第一个数交换位置;

第二次排序结果:[1, 2,3, 9, 8, 4] 在剩余的序列中最小的数2,与第二个数交换位置;

第三次排序结果:[1, 2, 3, 9, 8, 4] 在剩余的序列中最小的数3,自己本身,所以位置不变;

第四次排序结果:[1, 2, 3, 4, 8, 9] 在剩余的序列中最小的数4,与第四个数交换位置;

第五次排序结果:[1, 2, 3, 4, 8, 9] 在剩余的序列中最小的数8,自己本身,所以位置不变;

最后一个数已经是最大的数,不需要再次排序。

实现选择排序的步骤分解

排序次数

排序次数:序列长度 – 1(注意,不是比较次数);

因为序列中的最后一个数不需要再次比较大小,故排序次数为 序列长度 – 1。

找到最小的数

序列中找到最小的数,并记录该数的索引值;

因为minIndex默认开始为0,则第一个数无需与自身比较,所以j = i + 1;

// 遍历序列,找到最小的数
for (var j = i + 1; j < len; j++) {
    if (arr[j] < arr[minIndex]) {

        // 记录最小数的索引
        minIndex = j;
    };
};

在排序次数内多次遍历找到最小的数,因此需要再用一个for语句来进行控制。

// 排序次数
for (var i =   0; i < len - 1; i++) {
    // 默认最小数的索引为i
    minIndex = i;
    // 遍历序列,找到最小的数
    for (var j = i + 1; j < len; j++) {
        if (arr[j] < arr[minIndex]) {
            // 记录最小数的索引
            minIndex = j;
        };
    };
};

两数交换位置

利用temp变量,实现两数组元素之间数值的交换,也就是交互位置。

temp =   arr[i];
arr[i] =   arr[minIndex];
arr[minIndex]   = temp;
选择排序法完整代码
var arr = [9, 8, 3, 1, 2, 4],
    len = arr.length,
    minIndex, temp;
    // 排序次数
    for (var i =   0; i < len - 1; i++) {
        // 默认最小数的索引为i
        minIndex = i;
        // 遍历剩下的序列,找到最小的数
        for (var j = i + 1; j < len; j++) {
            if (arr[j] < arr[minIndex]) {
                // 记录最小数的索引
                minIndex = j;
            };
        };
    // HTML5学堂出品
    // 两数交互位置
    temp = arr[i];
    arr[i] = arr[minIndex];
    arr[minIndex] = temp;
};
console.log(arr);

选择排序法的效率

算法复杂度的基本概念

算法复杂度分为时间复杂度和空间复杂度(时间和空间是计算机最重要的资源,因此复杂度分为时间和空间)。

时间复杂度:指执行算法所需要的计算工作量;

空间复杂度:指执行算法所需要的内存空间。

时间复杂度:O(n*n)

时间复杂度是总运算次数表达式中受n的变化影响最大的项(不含系数);

第一次循环比较n-1次,然后是n-2次,n-3次,依此类推,最后一次循环比较1次,总的比较次数和为(n - 1 + 1) * n / 2,即进行比较操作的时间复杂度为O(n^2)

Tips:选择排序的比较次数与序列的初始排序无关。

空间复杂度:O(1)

排序算法需要一个额外的空间(temp变量)来交换元素的位置。

不稳定排序的一种算法

选择排序是一种不稳定排序的算法。

比如:序列[3, 8, 3, 1, 9 ],第一次循环第1个元素3会和1交换,变成[1, 8, 3, 3, 9],此时,原序列中两个3的先后顺序被破坏

原文发布于微信公众号 - HTML5学堂(h5course-com)

原文发表时间:2017-08-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏糊一笑

关于一道面试题【字符串 '1 + (5 - 2) * 3',怎么算出结果为10,'eval'除外】

最近徘徊在找工作和继续留任的纠结之中,在朋友的怂恿下去参加了一次面试,最后一道题目是: 写一个函数,输入一个字符串的运算式,返回计算之后的结果。例如这样的: ...

57110
来自专栏dalaoyang

递归基础思想

1753
来自专栏算法channel

常用排序算法代码兑现

主要推送关于对算法的思考以及应用的消息。坚信学会如何思考一个算法比单纯地掌握100个知识点重要100倍。本着严谨和准确的态度,目标是撰写实用和启发性的文章,欢迎...

35911
来自专栏北京马哥教育

史上最简单!冒泡、选择排序的Python实现及算法优化详解

1、排序概念 内部排序和外部排序 根据排序过程中,待排序的数据是否全部被放在内存中,分为两大类: 内部排序:指的是待排序的数据存放在计算机内存中进行的排序过程;...

5294
来自专栏数据结构与算法

P1168 中位数

题目描述 给出一个长度为N的非负整数序列A[i],对于所有 ]的中位数。 个数的中位数。 输入输出格式 输入格式: 输入文件median.in的第1...

32211
来自专栏Python小屋

Python内置函数int()高级用法

int()函数常用来把其他类型转换为整数,例如: >>> int(3.2) 3 >>> int(1/3) 0 其实,int是Python内置类型之一,之所以能...

3097
来自专栏HTML5学堂

原生JS | 当兔子遇到鸡

HTML5学堂-码匠:当兔子遇到鸡,会怎样呢?先别急,看个小视频~ 视频内容 当兔子遇到鸡 —— 不要害怕和别人不一样,在这个世界上,你就是独一无二的自己! 不...

49510
来自专栏编程之旅

唠唠快速排序算法

每一个从事计算机相关方向工作的同学一定听说过快速排序算法,在面试的准备过程中,快排也一定是一个必须要牢牢掌握的算法。那么今天就来唠唠快速排序算法。

1132
来自专栏Python小屋

Python模拟大整数乘法的小学竖式计算过程

让我们先看个图回顾一下小学学过的计算整数乘法的竖式计算过程 ? 然后再来看如何使用Python来模拟上面的过程,虽然在Python中计算任意大的数字乘法都没有问...

3475
来自专栏ml

向前字典排序

          next_permutation算法对区间元素进行一次组合排序,使之字典顺序大于原来的排序,有如下两个使用原形,对迭代器区间[first,l...

2739

扫码关注云+社区

领取腾讯云代金券