常见的排序算法有哪些?如何实现这些算法?

1.背景介绍


在计算机科学与数学中,一个排序算法是一种能将一串资料依照特定排序方式进行排列的一种算法。 最常用到的排序方式是数值顺序以及字典顺序。 排序算法用在处理文字资料以及产生人类可读的输出结果。 基本上,排序算法的输出必须遵守下列两个原则:

  • 输出结果为递增序列(递增是针对所需的排序顺序而言)
  • 输出结果是原输入的一种排列、或是重组
  • 虽然排序算法是一个简单的问题,但是从计算机科学发展以来,在此问题上已经有大量的研究。 更多的新算法仍在不断的被发明。

    2.知识剖析

    查找和排序算法是算法的入门知识,其经典思想可以用于很多算法当中。因为其实现代码较短,应用较常见。 所以在面试中经常会问到排序算法及其相关的问题。但万变不离其宗,只要熟悉了思想,灵活运用也不是难事。 一般在面试中最常考的是快速排序和归并排序,并且经常有面试官要求现场写出这两种排序的代码。 对这两种排序的代码一定要信手拈来才行。还有插入排序、冒泡排序、堆排序、基数排序、桶排序等。

    • 冒泡算法
    • 选择排序
    • 插入排序
    • 快速排序
    • 3.常见问题

      问题:如何用JavaScript 如何实现?

      4.解决方案

      冒泡排序

      冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素, 如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有元素再需要交换, 也就是说该数列已经排序完成。

      冒泡排序演算法的运作如下:

      1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
      2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
      3. 针对所有的元素重复以上的步骤,除了最后一个。
      4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
      5. 冒泡排序

        var examplearr=[8,94,15,88,55,76,21,39];

        function sortarr(arr){

        for(i=0;i

        for(j=0;j

        if(arr[j]>arr[j+1]){

        var temp=arr[j];

        arr[j]=arr[j+1];

        arr[j+1]=temp;

        }

        }

        }

        return arr;

        }

        sortarr(examplearr);

        console.log(examplearr);

        冒泡排序

        基本思路:1.依次比较相邻的两个数,如果第一个比第二个小,不变。如果第一个比第二个大,调换顺序。一轮下来,最后一个是最大的数

        2.对除了最后一个之外的数重复第一步,直到只剩一个数

        选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素, 然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

        选择排序的思想其实和冒泡排序有点类似,都是在一次排序后把最小的元素放到最前面。但是过程不同, 冒泡排序是通过相邻的比较和交换。而选择排序是通过对整体的选择。

        选择排序

        Array.prototype.selectionSort = function() {

        var i, j, min;

        var temp;

        for (i = 0; i < this.length - 1; i++) {

        min = i;

        for (j = i + 1; j < this.length; j++)

        if (this[min] > this[j])

        min = j;

        temp = this[min];

        this[min] = this[i];

        this[i] = temp;

        }

        return this;

        };

        var num = [22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70]; //定义一个数组

        num.selectionSort(); //数组定义选择排序算法

        选择排序

        1.找出最小的数,和第一个交换位置

        2.在剩下的数中,找出最二小的数,放在第二个

        3.依次类推,排出顺序

        插入排序也是一个简单直观的排序算法。它的 工作原理是通过构建有序序列,对于未排序数据, 在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序 (即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位, 为最新元素提供插入空间。

        1. 从第一个元素开始,该元素可以认为已经被排序
        2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
        3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
        4. 将新元素插入到该位置后
        5. 重复步骤2~5
        6. 插入排序

          Array.prototype.insertionSort = function () {

          for (var i = 1; i < this.length; i++) {

          var temp = this[i];

          var j = i - 1;

          //如果将赋值放到下一行的for循环内, 会导致在第13行出现j未声明的错误

          for (; j >= 0 && this[j] > temp; j--) {

          this[j + 1] = this[j];

          }

          this[j + 1] = temp;

          }

          return this;

          }

          var num = [22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70]; //定义一个数组

          num.insertionSort(); //数组调用插入排序算法

          插入排序

          基本思路:1.把数组分为[已排序]和[未排序]两部分,第一个数为[已排序],其余为[未排序]

          2.从[未排序]抽出第一个数,和[已排序]部分比较,插入到合适的位置

          快速排序

          步骤为:

          1. 从数列中挑出一个元素,称为"基准"(pivot),
          2. 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任一边)。在这个分割结束之后,该基准就处于数列的中间位置。这个称为分割(partition)操作。
          3. 递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。
          4. 递归到最底部时,数列的大小是零或一,也就是已经排序好了。这个演算法一定会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

            Array.prototype.quickSort = function() {

            var len = this.length;

            if (len <= 1)

            return this.slice(0);

            var left = [];

            var right = [];

            var mid = [this[0]];

            for (var i = 1; i < len; i++)

            if (this[i] < mid[0])

            left.push(this[i]);

            else

            right.push(this[i]);

            return left.quickSort().concat(mid.concat(right.quickSort()));

            };

            var arr = [5, 3, 7, 4, 1, 9, 8, 6, 2];

            arr = arr.quickSort();

            快速排序

            1.以一个数为基准(中间的数),比基准小的放到左边,比基准大的放到右边

            2.再按此方法对这两部分数据分别进行快速排序(递归进行

            3.不能再分后退出递归,并重新将数组合并

            5.编码实战

            6.扩展思考

            如何评价算法的好坏

            正确性

            算法能满足具体问题的需求,即对任何合法的输入算法都会得出正确的结果。

            可读性

            算法创建后由人来阅读、理解、使用以及修改。所以可读性的好坏直接影响到算法的好坏。如果一个算法涉及的想法很多,就会给阅读的人造成困难,那么这个算法就不能得到更好的交流和推广,更不便于对算法进行修改、扩展和维护。所以要提高算法的可读性,就要做到简明易懂。

            健壮性

            一个程序完成后,运行该程序的用户对程序的理解各有不同,并不能保证每一个人都能按照要求进行输入,健壮性就是指对非法输入的抵抗能力,当输入的数据非法时,算法能识别并做出处理,而不会因为输入的错误产生错误动作或造成瘫痪

            时间复杂度与空间复杂度

            时间复杂度简单地说就是算法运行所需要的时间。不同的算法具有不同的时间复杂度,当一个程序较小时感觉不到时间复杂度的重要性,当一个程序特别大时便会察觉到时间复杂度的重要性。所以如何写出更高速的算法一直是算法不断改进的目标。空间复杂度是指算法运行所需的存储空间,随着计算机硬件的发展,空间复杂度已经显得不再那么重要

            7.参考文献

            参考二:常见排序算法之JavaScript实现

            参考一:JavaScript 排序算法汇总

            最后编辑于
            ©著作权归作者所有,转载或内容合作请联系作者
            • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
              沈念sama阅读 194,088评论 5 459
            • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
              沈念sama阅读 81,715评论 2 371
            • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
              开封第一讲书人阅读 141,361评论 0 319
            • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
              开封第一讲书人阅读 52,099评论 1 263
            • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
              茶点故事阅读 60,987评论 4 355
            • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
              开封第一讲书人阅读 46,063评论 1 272
            • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
              沈念sama阅读 36,486评论 3 381
            • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
              开封第一讲书人阅读 35,175评论 0 253
            • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
              沈念sama阅读 39,440评论 1 290
            • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
              茶点故事阅读 34,518评论 2 309
            • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
              茶点故事阅读 36,305评论 1 326
            • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
              沈念sama阅读 32,190评论 3 312
            • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
              茶点故事阅读 37,550评论 3 298
            • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
              开封第一讲书人阅读 28,880评论 0 17
            • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
              开封第一讲书人阅读 30,152评论 1 250
            • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
              沈念sama阅读 41,451评论 2 341
            • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
              茶点故事阅读 40,637评论 2 335

            推荐阅读更多精彩内容

            • 又是一个周末,时间飞快,转眼一个月又将过去。 心想已经一个多月没有给家里打电话了,心中思绪万千,混乱绞痛夹着一丝丝...
              简默Trina阅读 181评论 0 1
            • 8.9-8.25 17个日夜,我在东莞度过。我不是去东莞度假,不是去玩乐。而是进了一家名为富强的电子厂,没错,在高...
              iiiiich阅读 177评论 0 0
            • 【作者 0han 本篇代码来源于实验楼shiyanlou.com】 这一篇没有太多介绍原理 因为是在学习pytho...
              0han阅读 2,412评论 0 1
            • 3月末 春天总算是来了 还带了点儿夏的气息 风吹地人 有些暖暖的 还有些懒懒的 吹地我 想起了3月的故乡 还有那长...
              goldfisher阅读 213评论 0 0
            • 上一次见到小七的时候,是高考前几个星期。我们站在圆形回廊上,她望着我,突然就说了一句:“前段时间他生日,我送了个画...
              待君浅笑阅读 165评论 6 5