javascript实现排序算法(二)

今天要介绍的是另一种排序算法,冒泡排序。冒泡排序和快速排序一样,都是属于交换排序,也就是都是通过判断某种条件,对数组进行交换操作,实现排序的算法。

对很多计算机专业的童鞋来说,冒泡排序算法应该是他们上在大学课堂上接触的第一种排序算法。大多数高校的计算机专业的第一门程序设计课应该都是C语言,我还记得是讲完流程控制语句和循环语句之后书中的一个例子介绍的就是冒泡排序算法。因为冒泡算法就和它的名字一样,非常的形象,排序过程很好理解,也不像快速排序那样,实现起来需要调用数组和日期的方法,以及递归的思想,掌握起来不那么容易。冒泡排序只需要简单逻辑判断语句以及循环语句就可以轻松实现。纵观八种排序算法,冒泡排序应该是最容易实现最容易理解的排序算法。

虽然冒泡排序的实现很简单,但是在日常开发中很少使用,因为它的平均时间复杂度为O(n2),这个和快速排序的nlg(n)时间复杂度相差太多,如果待排序的数组是千万级的上亿级的数据规模,那么进行一次的冒泡排序比快速排序多耗费的时间无疑是巨大的。不管对C端还是B端的用户来说,过长的时间查询都是极差的用户体验,如果在淘宝上输入一个搜索条件,几秒钟都没有出结果我相信可能很少有人会选择继续等待。因此对网站来说,效率就是生命,时间就是金钱。

即使冒泡排序的效率低,耗费的时间长,但是任何东西都有正反两面,世界上一切的存在都是合理的,再优秀的人也有弱点,再平庸的人也有擅长的一面。而冒泡排序也不例外,它是一个稳定的排序算法,而快速排序算法是不稳定的排序算法。在排序中的所谓的稳定性指的是,如果在数组中两个值相等,则在排序之后不会改变这两个值的位置,这个是快速排序不具备的,如果两个元素相等的时候,冒泡排序不会进行交换,但是快速排序仅仅通过基准进行判断,在有些情况下会对相等的元素进行交换。废话不多说了,下面开始介绍冒泡排序的算法和实现。

上一篇博客我把快速排序归纳为两个步骤,那么以简单著称的冒泡排序只需要用一步就可以实现:

1、从数组的第一个开始两两比较,如果前面的元素大于后面的元素,两个元素交换。

2、忽略最后一个元素,重复第一步。

虽然这两句话看起来简单明了,但是我还是要举一个例子,形象的解释一下这个过程:

待排序数组:[3,2,1];

第一遍处理:[2,3,1]——>[2,1,3]

第二遍处理:[1,2,3]

可以看见,第一遍处理的时候,3和2进行比较,3比2大,3和2交换,然后3和1进行比较,3大于1,3和1进行交换。这时候,数组中最大的元素,被移动到了最后一位,这就是第一遍的效果,而第二遍,2和1进行比较,2比1大,2和1进行交换,然后由于最大的就是3,不需要交换。这样第二大的元素被放到了倒数第二位,还剩一个1自然就是最小的元素。整个排序的过程就和一个气泡从一个试管里浮上来,而最大的元素就是那个气泡,其他的元素构成了这个试管。我觉得有的时候,千言万语都赶不上一段代码来的实在,这也许就是说和做的区别,接下来我就来介绍一下冒泡排序算法的代码实现。

首先定义一个排序函数,接收一个待排序的数组作为参数,如果数组的长度小于二直接将数组返回。

function bubbleSort(arr) {

  if(arr.length<2){

    return arr;

   }

}

准备工作做完下面进行第一步:从数组的第一个开始两两比较,如果前面的元素大于后面的元素,两个元素交换和第二步:忽略最后一个元素,重复第一步。

这一步中需要解释的有两个部分,首先需要解释的是两个元素进行交换的操作,原理很简单,定义一个空的元素,用来做两个元素的中间变量,就好比现在有两个球,分别在你的左手和右手,要将这两个球从你的双手交换位置,但是一个手只允许放一个球,这个时候你需要第三个容器先把左手的球放到容器里,再把右手的球放到左手里,然后用右手拿起容器里面的球,这样就实现了左右手球的交换操作。

接下来是嵌套的for循环,刚才介绍算法的时候,举的例子[3,2,1],第一遍是两次交换,第二遍是一次交换。第三遍是0次交换。在程序中,外层循环控制的就是排序算法的操作的遍数,而内层循环控制的才是真正每遍循环需要进行交换操作的次数,通过简单的观察可以看出这样的规律,每次交换的次数=数组的长度-第几遍,在两次for循环之后就得到了排序之后的数组。虽然解释的不那么标准和官方,但是真的懂了就是最好的。接下来是代码实现,这个时候不得不小小的吐槽一下简书的富文本编辑器,在这上面敲代码好难,还是截图吧。


虽然在代码量上并没有比快速排序少很多,但是算法的复杂度上,实现的难度上确实简单很多。

关于冒泡排序的算法就介绍到这,接下来聊点题外话。接下来聊点我的一点小想法,可能不太成熟,希望前辈大神们批评指正,在上面我举的第一个例子,[3,2,1],数组的长度为3,第一遍处理进行了两次交换操作,第二遍处理进行了一次交换操作。一共1+2次交换。试想一下,如果数组的长度为4,一共会进行3+2+1次交换操作。就在写这篇博客的时候,看到了这两串数字,就让我想起了高中学过的数学知识,等差数列,每次的交换次数恰恰是等差数列的求和公式,

在算法中,假设n为无穷大,n在n2面前可以忽略不计所以n+n2就是n2,而1/2*n2也就是n2,因此,可以得出如果要进行冒泡排序最坏的情况下需要进行n2次交换操作,所以时间复杂度为O(n2)。这也许是比较另类的冒泡排序算法的时间复杂度的推导方式。

写完了两篇博客,最大的感受是觉得自己收获了真的很多,渐渐发现,分享真的是很美好的,在写博客的过程中会弥补很多自己的知识漏洞,提升自己,在写完第一篇快速排序算法的当天晚上,连做梦都在写那一段代码。把一件事情讲明白,自己也就很透彻的明白了,比读书,查资料真的要高效的多。如果在博客中有错误,或者不足都希望前辈们批评指正。

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

推荐阅读更多精彩内容