游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

总结五种比较高效常用的排序算法

  说到排序算法,大家估计都比较熟悉,但要你一下子写出来又蒙圈了。所以这篇文章不会讲解所有的排序算法,而是挑选最热门的五种:冒泡排序、选择排序、插入排序、快速排序、归并排序。
  我们通过图文流程解释的方式,让大家能快速领悟到各个排序算法的思想,从而达到快速掌握的目的。此外每个排序算法都有对应的Github代码实现,可供大家调试理解算法。同时也附上了文章中所画图的draw。io数据文件,方便大家根据自己的习惯进行修改。
  排序算法的仓库地址:javacodechipsrcmainjavatechshuyijavacodechipsortatmasterchenyurongjavacodechip
  如果你已经不是第一次学习排序算法,那么我建议你按照这样的思路学习:通过图解或调试,弄清楚每个算法的思想。下载Github例子,尝试自己手写实现。定期复习手写实现,不断巩固知识点。
  好了,废话不多说,让我们开始今天的图解排序算法吧!选择排序
  选择排序,意思是每次从待排序的元素选出极值作为首元素,直到所有元素排完为止。其详细的排序逻辑如下图所示:第1次,index下标对应值为9,找出所有最小值为1,将9与1交换位置,得到。同时,index下标加一。第2次,index下标对应值为3,找出所有最小值为3,将3与2交换位置,得到。同时,index下标加一。第3次,index下标对应值为9,找出所有最小值为3,将9与3交换位置,得到。同时,index下标加一。一直这样循环下去,直到index下标到达数组边界,如所示。
  注意:灰色部分表示已经完成排序的部分。
  选择排序的算法比较简单,如下所示:publicstaticvoidselectSort(int〔〕arr){for(inti0;iarr。length1;i){intmini;每一趟循环比较时,min用于存放较小元素的数组下标,这样当前批次比较完毕最终存放的就是此趟内最小的元素的下标,避免每次遇到较小元素都要进行交换。for(intji1;jarr。length;j){if(arr〔j〕arr〔min〕){minj;}}进行交换,如果min发生变化,则进行交换if(min!i){swap(arr,min,i);}}}
  可调式代码地址:javacodechipSelectSort。javaatmasterchenyurongjavacodechip
  简单选择排序通过上面优化之后,无论数组原始排列如何,比较次数是不变的;对于交换操作,在最好情况下也就是数组完全有序的时候,无需任何交换移动,在最差情况下,也就是数组倒序的时候,交换次数为n1次。综合下来,时间复杂度为O(n2)。冒泡排序
  冒泡排序,就是像池塘里的水泡一样往上冒泡。我们可以理解成一个数不断地往上冒泡(比较交换),一直到最上面(末尾)。通过不断往上冒泡,每次冒泡都会将最值浮到最上层,最终达到完全有序。其详细的排序算法逻辑如下:第1轮,9大于3,那么将9与3交换,接着继续往下比较。9大于1,那么将9与1交换,接着往下比较,最终我们将9浮到数组顶端。此时index指向数组顶端,该数是有序的了,因此index减一。第2轮,3大于1,那么3与1交换,接着往下比较。最终,我们只需要比较到index位置即可,最终我们将7浮到数组顶端。同时index也减一,此时7、9是有序的。如此这样反复循环,直到index下标达到0即可。
  在冒泡排序的过程中,如果某一趟执行完毕,没有做任何一次交换操作,那么就说明剩下的序列已经是有序的了。例如数组〔5,4,1,2,3〕,执行了两次冒泡之后,其数组变为〔1,2,3,4,5〕。此时,index下标指向3这个值。再执行第三次冒泡时,我们会发现123,我们一次交换都没有做,这就说明剩下的序列已经是有序的,排序操作已经完成,不需要再进行排序了。publicstaticvoidbubbleSort(int〔〕arr){for(inti0;iarr。length1;i){booleanflagtrue;设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已然完成。for(intj0;jarr。length1i;j){if(arr〔j〕arr〔j1〕){swap(arr,j,j1);flagfalse;}}if(flag){break;}}}
  可调试代码地址:javacodechipBubbleSort。javaatmasterchenyurongjavacodechip插入排序
  插入排序,即将元素一个个插入新的数组系列中,直到所有元素插完为止。例如下图的例子,第1次将元素9插入新的数组中
  插入排序paramarrpublicstaticvoidinsertSort(int〔〕arr){for(inti1;iarr。length;i){intji;while(j0arr〔j1〕arr〔j〕){swap(arr,j,j1);j;}}}
  可调式代码地址:javacodechipInsertSort。javaatmasterchenyurongjavacodechip
  简单插入排序在最好情况下,需要比较n1次,无需交换元素,时间复杂度为O(n);在最坏情况下,时间复杂度依然为O(n2)。但是在数组元素随机排列的情况下,插入排序还是要优于上面两种排序的。快速排序
  快速排序,顾名思义其排序效率非常高,所以才叫快速排序。快速排序的核心思想是选取一个基准数,通过一趟排序将小于此基准数的数字放到左边,将大于此基准数的数字放到右边。之后再用遍历不断地对左右子串进行同样的操作,从而达到排序的目的。快速排序的时间复杂度在最坏情况下是O(N2),平均的时间复杂度是O(NlgN)。
  例如下图中的例子,在第一趟排序里,我们选中了基准数为9,那么此次排序就把所有比9小的数放到了左边,所有比9大的数放到了右边。在第二趟排序里,我们选中了基准数为7,那么此次排序就把所有比7小的数放到了左边,所有比7大的数放到了右边。
  我们以对931427整数串进行排序为例,详细讲解整个快速排序的流程:选取9为基准数,从right开始,从右到左找出第一个小于9的数。第一个数是7,小于9,符合条件。于是将找到的这个数值放到left位置上,同时left加一。从left开始,从左到右选取第一个大于9的数。可以看到子串中并没有一个大于9的数,于是left会一直累加到right的位置。当leftright时,单趟排序结束,将基准数填入left所在位置。最终整个字符串被以9为基准数,切割成两部分,左边部分比9小,右边部分比9大。
  接着进行第二次排序,第二次排序的整体流程如下:选取7为基准数,从right开始,从右到左找出第一个小于9的数。第一个数是2,小于9,符合条件。于是将找到的这个数值放到left位置上,同时left加一,此时数组变为:231429。从left开始,从左到右选取第一个大于9的数。可以看到子串中并没有一个大于9的数,于是left会一直累加到right的位置。当leftright时,单趟排序结束,将基准数填入left所在位置。最终整个字符串被以7为基准数,切割成两部分,左边部分比7小,右边部分比7大。
  剩余的子串都进行同样的处理逻辑,最终我们可以得到一个排序的整数串。
  代码实现:vparamarr待排序的数组paraml数组的左边界(例如,从起始位置开始排序,则l0)paramr数组的右边界(例如,排序截至到数组末尾,则rarr。length1)publicstaticvoidquickSort(intarr〔〕,intl,intr){if(lr){inti,j,x;il;jr;xarr〔i〕;while(ij){从右向左找第一个小于x的数while(ijarr〔j〕x){j;}if(ij){arr〔i〕arr〔j〕;i;}从左向右找第一个大于x的数while(ijarr〔i〕x){i;}if(ij){arr〔j〕arr〔i〕;j;}}arr〔i〕x;quickSort(arr,l,i1);quickSort(arr,i1,r);}}
  可调式代码地址:javacodechipQuickSort。javaatmasterchenyurongjavacodechip
  参考:快速排序如果天空不死博客园归并排序
  归并排序,其英文名为MergeSort,其意思是将排序串拆分成最小的单位之后,再一个个合并成有序的子串。例如下图的整数串,将其拆分成最小的子串就是每个只有一个整数。之后再将每个单个的子串合并起来,例如:8与4合并起来成为有序子串4、8,5与7合并起来成为有序子串5、7。4、8和5、7再合并成为有序子串4、5、7、8。
  可以看到在这个过程中,最关键是合并两个有序子串的算法。这里我们以〔4,5,7,8〕和〔1,2,3,6〕为例,讲解有序子串合并的算法流程。首先声明一个与原有数组相同的长度的临时数组temp。接着i指向子串1开始的位置,j指向子串2开始的位置。接着比较arr1〔i〕与arr2〔j〕的值,找出较小值。因为两个子串都是有序的,所以这两个值中的最小值,就是整个串中的最小值。找出最小值后将其值放入temp的开始位置,最小值对应的子串下标加1。这里可以看到是41,即子串arr2的值较小,那么将1放入temp〔0〕位置,接着j加一,此时j指向2。接着继续对比i和j两个数的大小,继续对比步骤2的逻辑。这里可以看到arr〔i〕4arr〔j〕2,那么应该将较小值放入temp数组中,即将2放入数组中,并且将j1,即j2,此时j指向的值为3。按着上述的步骤继续不断重复步骤2的内容,我们会看到子串2首先到末尾。此时子串1还剩下一些数值,这些数值肯定是更大的值,那么直接将这些数值复制到temp数组中即可。如果子串1先到末尾,那么就应该将子串2剩余的数值写入temp数组。最后,将temp的数值写回原有数组中即可。
  代码实现:publicstaticvoidsort(int〔〕arr){在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间int〔〕tempnewint〔arr。length〕;sort(arr,0,arr。length1,temp);}privatestaticvoidsort(int〔〕arr,intleft,intright,int〔〕temp){if(leftright){intmid(leftright)2;左边归并排序,使得左子序列有序sort(arr,left,mid,temp);右边归并排序,使得右子序列有序sort(arr,mid1,right,temp);将两个有序子数组合并操作merge(arr,left,mid,right,temp);}}privatestaticvoidmerge(int〔〕arr,intleft,intmid,intright,int〔〕temp){左序列指针intileft;右序列指针intjmid1;临时数组指针intt0;while(imidjright){if(arr〔i〕arr〔j〕){temp〔t〕arr〔i〕;}else{temp〔t〕arr〔j〕;}}将左边剩余元素填充进temp中while(imid){temp〔t〕arr〔i〕;}将右序列剩余元素填充进temp中while(jright){temp〔t〕arr〔j〕;}t0;将temp中的元素全部拷贝到原数组中while(leftright){arr〔left〕temp〔t〕;}}
  可调试代码地址:javacodechipMergeSort。javaatmasterchenyurongjavacodechip算法对比选择排序与冒泡排序的区别?
  选择排序是每次选出最值,然后放到数组头部。而冒泡排序则是不断地两两对比,将最值放到数组尾部。本质上,他俩每次都是选出最值,然后放到一边。
  其最大的不同点是:选择排序只需要做一次交换,而冒泡排序则需要两两对比交换,所以冒泡排序的效率相对来说会低一些,因为会做多一些无意义的交换操作。快速排序与归并排序的区别?
  刚刚看了一下,快速排序和归并排序,我觉得差别可以提现在拆分合并的过程中,比较的时机。
  快排和归并,都是不断拆分到最细。但是归并更纯粹,拆分时不做比较,直接拆!而快排还是会比较一下的。所以在拆分阶段,快排会比归并耗时一些。
  而因为快排在拆分阶段会比较,所以其拆得没有归并多层级,因此其在合并阶段就少做一些功夫,会快一些。
  所以快排和归并排序的区别,本质上就是拆分、合并的区别。
  原文链接:https:www。cnblogs。comchanshuyiptopfivesortalgorithm。html

轩逸成燃油车最后遮羞布!纯燃油车的时代,真的要结束了2022年汽车市场的销量已经表明,纯燃油车的时代,真的要结束了。首先为了防杠,定义什么叫纯燃油车,单纯依靠发动机驱动,不依赖任何电机驱动的车辆,也就是我们所说的传统燃油车……托马斯还是凯恩?一名英超球星因性侵被捕,8人晒图自证清白平地一声惊雷!转会市场火热进行,英伦足坛有人站出来抢热点了,来自电讯报、太阳报的爆料,有一名来自伦敦球队的英超球星因为性侵犯被抓,他是在自家别墅被警察带走,审讯了15个小时,目……分享大龄熟女该如何护肤?世上没有丑女人,只有懒女人,要美就要开始行动啦!什么时候都不晚!好好保养,好好爱自己,做个美腻冻龄的女人首先,要进行清洁图片来源于网络清洁是第一步,否则皮肤的……孩子牙齿被磕掉,做好这3步,掉落的牙齿还可能长回去孩子摔了一跤,把牙摔掉了。该怎么办呀?这类的信息,在后台经常看到。国际牙外伤协会,曾在《牙外伤临床指南》中讲道,口腔外伤在各类外伤中占比最高,高达5。据统计,学前班的孩子……文案丨温柔扑空了才会长记性01hr要是那天,我抓住你就好了。02hr我的满心欢喜,也该告一段落了。03hr你不必冷淡和敷衍,我没想过纠缠。04hr你不能因为一句对不起就带走我那么……网红唐小鱼穿高跟鞋趟水捞蟹,手锤蒜成焦点,网友是不是怀孕了网红成了大家关注的群体,在日常生活中刷视频消遣时间,总会从中认识一些有趣灵魂的网红,给大家带来快乐,他们各凭本事,各显神通,带来吸睛独特的作品。近日,一位名叫唐小鱼的网红……中国最高的树在哪里?惊心动魄的热带雨林,在60米高的树冠上行望天树景区其实是西双版纳热带雨林国家公园的一部分,这片北纬21度的绿洲是西双版纳热带雨林的核心。这里距离磨憨口岸仅60公里,距离老挝南塔省城120km,甚至比到景洪市还要更近一……12月手机性能榜游戏手机很尴尬旗舰蓝绿厂胜出中端荣耀霸榜就在元旦小长假期间,国内手机市场也没闲着,除了多家智能手机品牌陆续预热了自家新机之外,2021年最后一期手机性能排行榜也正式公布了出来,根据公布的排行榜来看,其中并没有已经发布……位于江西深处,有个雄奇险秀,水景怡人之地,现为吸氧好去处随着这两年大家对健康日益看重,健康游越来越受欢迎,其中洗肺游名列第一!何为洗肺游呢?简单来说,就是游客开始大量朝着氧吧型旅游目的地游玩,这样一来,不但可以强身健体,还可以欣赏到……28nm芯片究竟有多受欢迎?看完这个你就知晓近日,一则分析报告称。2021年,全球对于半导体的销售额创下了一个新的纪元,同比上涨26。2,合计达5559亿美元。而这个数额,是其他任何领域都无法企及的。可见,半导体市场无论……在现役联盟中,仅有5人算进攻万花筒,布克和卡椒组合全都上榜目前NBA对进攻更加鼓励,毕竟场均30分也没有那么高的难度了,单场拿高分也没有那么高的难度了。然而进攻万花筒那确实是难得一见,他们这种玩家并非只是一招鲜,或者迷恋三分和罚球。他……中国滑雪公主谷爱凌,名字中有母亲的心酸事,让人为之感动得想哭生的名字,往往有父母、长辈们美好的期许,名字也是伴随学生一生的标签,家长们为了起一个好名字,可谓是绞尽脑汁。父母给学生起名字的方法是多种多样,有的翻书、品学网,找几个好听……
中国人寿寿险公司承办大病保险项目200多个,覆盖近3。5亿城近日,中国银保监会发布了《关于推进普惠保险高质量发展的指导意见(征求意见稿)》(下称征求意见稿),明确指出发展普惠保险对完善多层次社会保障体系,提升人民群众总体保障水平,助力全……体坛联播切尔西利物浦互交白卷,德约豪取澳网24连胜利物浦战平切尔西。本文图片CFP即便克洛普迎来自己的千场执教里程碑,即便亿欧先生穆德里克在首秀中表现得可圈可点,依旧无法掩盖利物浦和切尔西近段时间的尴尬。北京时间1……火箭连续三年倒数第一,已厌倦大厦的老将,为寻找冠军而出发吗?戈登可能会离开球队。休斯顿从20202021赛季开始结束了詹姆斯哈登的时代,正式进入了大厦。收集希望之星的工作还算不错。在不长的时间里,第一格林、小贾巴里史密斯、阿尔费伦……微软统计Office201320102007版本用户数IT之家1月20日消息,微软希望检查仍在使用不受支持的Office版本(以及即将不受支持的Office2013版本)的用户数量,微软将通过正在推送的KB5021751更新补丁来……14亿千米外回望地球,卡西尼号探测器的这张照片让人感到不可思太阳系有八大行星:水星、金星、地球、火星、木星、土星、天王星、海王星,最前面的4颗行星是类地行星,后面的4颗行星是气态行星,其中火星和地球都处于太阳系的宜居地带,两者存在很多相……亲人去世该不该告诉孩子?正确的死亡教育,更能让孩子珍惜生命文小鱼奶爸日记原创,欢迎个人转发和分享世界上有很多相对立的存在,这些存在之间的关系不仅仅是对立,其实也是为了更好地平衡。生和死就是这样既对立又平衡的存在,但生代表了……西藏自驾游注意事项我两次到过西藏,其中2019年青进川出一人一车自驾游西藏。看到这个问题,我来详细回答一下。我从准备工作、路线图、花费、注意事项等几个方面来全面回答一下这个问题,希望能对大……看了韩国代表队的新闻发布会,他们这种无理闹三分的劲儿随谁呢?新闻发布会看了,气不打一处来!那意思,为了自己运动员,先忍了,不抵制冬奥会了,让其他韩国运动员比完赛再说!自己摔倒了,还要怪别人?看了一些韩国的媒体报道,满眼望去,……苹果公司赠送的这个赠品,别把它弄丢了!小小一个价值145元即便人们总是说乔布斯走后苹果手机一代不如一代,但至今为止,每一次出现新款苹果手机都会遭到许多人疯抢,从手机的运行速度上来看,苹果手机的运行速度还是很快的,并且不会出现卡顿,即便……杭州微念已退出李子柒公司股东行列红星资本局2月2日消息,李子柒与杭州微念品牌管理有限公司(以下简称杭州微念)达成和解后,近日,四川子柒文化传播有限公司(以下简称子柒文化)发生工商变更,据天眼查,杭州微念已退出……雄浑北盘江贵州高原切出的绝美诗篇在贵州高原西部广阔的喀斯特山原中,有一条大江奔腾前进,将大地切割得沟谷纵横,只剩下一片嶙峋的石海。这条江曾以不同的名字出现在两千多年来的各种史册里:古称牂牁江,魏时称盘江;上游……2022业绩爆表,2023年储能行业发展动能十足储能产业定位与商业模式正日渐清晰,从近期行业公布的业绩预喜看,储能行业业绩持续爆发,多家公司预计2022年业绩翻倍,再为行业增添利好。市场普遍认为,2023年储能将成为最……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网