zoukankan      html  css  js  c++  java
  • 算法之旅 | 选择排序法

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

    算法的基本概念

    算法是什么,它有何作用

    为解决一个问题而采取的方法和步骤,称为算法。
    我们可以把算法看成一本“福字剪纸教程”,其中每一种算法就是剪纸教程中的一种包含“固定步骤”的剪纸方法,使用者只要按照步骤进行剪纸,就可以剪出好看的福字。
    之所以有这么多的算法,在于不同算法解决问题的效率各有不同适合不同的场景。随着问题规模的增长,算法之间的差距会变的不可跨越。提升解决问题的效率,不仅仅依赖于选择快速的硬件,还依赖于选择有效(适合)的算法。

    排序的使用场景

    针对数组进行从大到小(或从小到大)的排序。例如:管理系统中按照成绩的排序,按阅读量对文章的排序等。
    数据快速的计算与排序,与前端页面性能有直接的关系。(譬如在页面中有10000条的数据需要靠JS进行排序,采用不同的算法所消耗的时间差距甚大,直接影响着网站的用户体验)

    常见的排序方法

    较为常见的排序方法,包括:冒泡排序、选择排序、快速排序、二分法插入排序等。
    由于排序的算法有很多,在本次“算法系列”的分享当中,我们先从简单易上手的选择排序法开始,其它的排序算法会随后陆续跟大家一起分享。

    选择排序法的基本原理

    先找到序列中最小的数,将它和序列中第一个数交换位置;
    接下来,在剩下的序列中继续此操作:找到最小的数,将它和序列中的第二个数交换位置;
    依此类推,直到将整个序列排序完成。
    简言之,选择排序就是 —— 不断地选择剩余序列中最小者,然后与未排序数列的“第一个”数字交换位置。

    案例说明

    图片描述

    实现选择排序的步骤分解

    排序次数

    排序次数:序列长度 – 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);
    

    欢迎沟通交流~~~HTML5学堂(码匠)

    选择排序法的效率

    算法复杂度的基本概念

    算法复杂度分为时间复杂度和空间复杂度(时间和空间是计算机最重要的资源,因此复杂度分为时间和空间)。
    时间复杂度:指执行算法所需要的计算工作量;
    空间复杂度:指执行算法所需要的内存空间。

    时间复杂度: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的先后顺序被破坏。

    clipboard.png

    clipboard.png

  • 相关阅读:
    poj 3068 Bridge Across Islands
    XidianOJ 1086 Flappy v8
    XidianOJ 1036 分配宝藏
    XidianOJ 1090 爬树的V8
    XidianOJ 1088 AK后的V8
    XidianOJ 1062 Black King Bar
    XidianOJ 1091 看Dota视频的V8
    XidianOJ 1098 突击数论前的xry111
    XidianOJ 1019 自然数的秘密
    XidianOJ 1109 Too Naive
  • 原文地址:https://www.cnblogs.com/10manongit/p/12867417.html
Copyright © 2011-2022 走看看