范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

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

  说到排序算法,大家估计都比较熟悉,但要你一下子写出来又蒙圈了。所以这篇文章不会讲解所有的排序算法,而是挑选最热门的五种:冒泡排序、选择排序、插入排序、快速排序、归并排序。
  我们通过 图文 + 流程解释   的方式,让大家能快速领悟到各个排序算法的思想,从而达到快速掌握的目的。此外每个排序算法都有对应的 Github 代码实现,可供大家调试理解算法。同时也附上了文章中所画图的 draw.io 数据文件,方便大家根据自己的习惯进行修改。
  排序算法的仓库地址:java-code-chip/src/main/java/tech/shuyi/javacodechip/sort at master · chenyurong/java-code-chip
  如果你已经不是第一次学习排序算法,那么我建议你按照这样的思路学习: 通过图解或调试,弄清楚每个算法的思想。 下载 Github 例子,尝试自己手写实现。 定期复习手写实现,不断巩固知识点。
  好了,废话不多说,让我们开始今天的图解排序算法吧! 选择排序
  选择排序,意思是每次从待排序的元素选出极值作为首元素,直到所有元素排完为止。  其详细的排序逻辑如下图所示: 第 1 次,index 下标对应值为 9,找出所有最小值为 1,将 9 与 1 交换位置,得到 ②。同时,index 下标加一。 第 2 次,index 下标对应值为 3,找出所有最小值为 3,将 3 与 2 交换位置,得到 ③。同时,index 下标加一。 第 3 次,index 下标对应值为 9,找出所有最小值为 3,将 9 与 3 交换位置,得到 ④。同时,index 下标加一。 一直这样循环下去,直到 index 下标到达数组边界,如 ⑥ 所示。
  注意:灰色部分表示已经完成排序的部分。
  选择排序的算法比较简单,如下所示: public static void selectSort(int[] arr) {     for (int i = 0; i < arr.length - 1; i++) {         int min = i;//每一趟循环比较时,min用于存放较小元素的数组下标,这样当前批次比较完毕最终存放的就是此趟内最小的元素的下标,避免每次遇到较小元素都要进行交换。         for (int j = i + 1; j < arr.length; j++) {             if (arr[j] < arr[min]) {                 min = j;             }         }         //进行交换,如果min发生变化,则进行交换         if (min != i) {             swap(arr,min,i);         }     } }
  可调式代码地址:java-code-chip/SelectSort.java at master · chenyurong/java-code-chip
  简单选择排序通过上面优化之后,无论数组原始排列如何,比较次数是不变的;对于交换操作,在最好情况下也就是数组完全有序的时候,无需任何交换移动,在最差情况下,也就是数组倒序的时候,交换次数为n-1次。综合下来,时间复杂度为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 这个值。再执行第三次冒泡时,我们会发现 1<2<3,我们一次交换都没有做,这就说明剩下的序列已经是有序的,排序操作已经完成,不需要再进行排序了。 public static void bubbleSort(int[] arr) {     for (int i = 0; i < arr.length - 1; i++) {         boolean flag = true;//设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已然完成。         for (int j = 0; j < arr.length - 1 - i; j++) {             if (arr[j] > arr[j + 1]) {                 swap(arr,j,j+1);                 flag = false;             }         }         if (flag) {             break;         }     } }
  可调试代码地址:java-code-chip/BubbleSort.java at master · chenyurong/java-code-chip 插入排序
  插入排序,即将元素一个个插入新的数组系列中,直到所有元素插完为止。  例如下图的例子,第 1 次将元素 9 插入新的数组中
  /**  * 插入排序  *  * @param arr  */ public static void insertSort(int[] arr) {     for (int i = 1; i < arr.length; i++) {         int j = i;         while (j > 0 && arr[j - 1] > arr[j]) {             swap(arr,j,j-1);             j--;         }     } }
  可调式代码地址:java-code-chip/InsertSort.java at master · chenyurong/java-code-chip
  简单插入排序在最好情况下,需要比较n-1次,无需交换元素,时间复杂度为O(n);在最坏情况下,时间复杂度依然为O(n2)。但是在数组元素随机排列的情况下,插入排序还是要优于上面两种排序的。 快速排序
  快速排序,顾名思义其排序效率非常高,所以才叫快速排序。快速排序的核心思想是选取一个基准数,通过一趟排序将小于此基准数的数字放到左边,将大于此基准数的数字放到右边。之后再用遍历不断地对左右子串进行同样的操作,从而达到排序的目的。  快速排序的时间复杂度在最坏情况下是 O(N2),平均的时间复杂度是 O(N*lgN)。
  例如下图中的例子,在第一趟排序里,我们选中了基准数为 9,那么此次排序就把所有比 9 小的数放到了左边,所有比 9 大的数放到了右边。在第二趟排序里,我们选中了基准数为 7,那么此次排序就把所有比 7 小的数放到了左边,所有比 7 大的数放到了右边。
  我们以对  9 3 1 4 2 7   整数串进行排序为例,详细讲解整个快速排序的流程: 选取 9 为基准数,从 right 开始,从右到左找出第一个小于 9 的数。 第一个数是 7,小于 9,符合条件。于是将找到的这个数值放到 left 位置上,同时 left 加一。 从 left 开始,从左到右选取第一个大于 9 的数。 可以看到子串中并没有一个大于 9 的数,于是 left 会一直累加到 right 的位置。 当 left >= right 时,单趟排序结束,将基准数填入 left 所在位置。 最终整个字符串被以 9 为基准数,切割成两部分,左边部分比 9 小,右边部分比 9 大。
  接着进行第二次排序,第二次排序的整体流程如下: 选取 7 为基准数,从 right 开始,从右到左找出第一个小于 9 的数。 第一个数是 2,小于 9,符合条件。于是将找到的这个数值放到 left 位置上,同时 left 加一,此时数组变为:2 3 1 4 2 9。 从 left 开始,从左到右选取第一个大于 9 的数。 可以看到子串中并没有一个大于 9 的数,于是 left 会一直累加到 right 的位置。 当 left >= right 时,单趟排序结束,将基准数填入 left 所在位置。 最终整个字符串被以 7 为基准数,切割成两部分,左边部分比 7 小,右边部分比 7 大。
  剩余的子串都进行同样的处理逻辑,最终我们可以得到一个排序的整数串。
  代码实现: /**  * v  * @param arr -- 待排序的数组  * @param l -- 数组的左边界(例如,从起始位置开始排序,则l=0)  * @param r -- 数组的右边界(例如,排序截至到数组末尾,则r=arr.length-1)  */ public static void quickSort(int arr[], int l, int r) {     if (l < r) {         int i,j,x;          i = l;         j = r;         x = arr[i];         while (i < j)         {             // 从右向左找第一个小于x的数             while(i < j && arr[j] > x) {                 j--;             }             if(i < j) {                 arr[i] = arr[j];                 i++;             }             // 从左向右找第一个大于x的数             while(i < j && arr[i] < x) {                 i++;             }             if(i < j) {                 arr[j] = arr[i];                 j--;             }         }         arr[i] = x;         quickSort(arr, l, i-1);         quickSort(arr, i+1, r);     } }
  可调式代码地址:java-code-chip/QuickSort.java at master · chenyurong/java-code-chip
  参考:快速排序 - 如果天空不死 - 博客园 归并排序
  归并排序,其英文名为 Merge Sort,其意思是将排序串拆分成最小的单位之后,再一个个合并成有序的子串。  例如下图的整数串,将其拆分成最小的子串就是每个只有一个整数。之后再将每个单个的子串合并起来,例如: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。这里可以看到是 4 < 1,即子串 arr2 的值较小,那么将 1 放入 temp[0] 位置,接着 j 加一,此时 j 指向 2。 接着继续对比 i 和 j 两个数的大小,继续对比步骤 2 的逻辑。这里可以看到 arr[i]=4 < arr[j]=2,那么应该将较小值放入 temp 数组中,即将 2 放入数组中,并且将 j + 1,即 j = 2,此时 j 指向的值 为 3。 按着上述的步骤继续不断重复步骤 2 的内容,我们会看到子串 2 首先到末尾。此时子串 1 还剩下一些数值,这些数值肯定是更大的值,那么直接将这些数值复制到 temp 数组中即可。如果子串 1 先到末尾,那么就应该将子串 2 剩余的数值写入 temp 数组。 最后,将 temp 的数值写回原有数组中即可。
  代码实现: public static void sort(int []arr){     //在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间     int []temp = new int[arr.length];     sort(arr,0,arr.length-1,temp); } private static void sort(int[] arr,int left,int right,int []temp){     if(left
c夯实基础2之前发布c夯实基础委托,有网友说说另外一种理解委托就是指针,指向一个静态的函数或者已经实例化的一个对像的函数。委托就是指针这句话比较形象,可以指向符合委托形式的任何函数。以下是两种约2000元?它比iPhone还好看还记得之前的OriginOcean演示机吗?当时很多网友都点赞比iPhone还看好看!,纷纷催促vivo赶紧发布。机长当时也以为这就是即将发布的vivo12系列,很是蛮期待的。可是域名与网址有什么区别?简单的说,一个网站必须是域名,有了域名别人才能访问,网址存在于域名中,很多人错误的理解为网址就是域名,实际上网址是域名的一个延申。如果你有注册域名的意向,推荐bluehost,你想想在农村老家安装网络摄像头,哪个牌子的好呢?如果是需要安装在院子里或者大门口的话,那最好是选择海康或者大华专业的工程用摄像头,能支持防水防尘,不过一般需要额外拉网线,布线什么的,安装会相对麻烦一点。不过,现在很多家用摄像头,埃隆马斯克的隧道公司Boringcompany完成6。75亿美元C轮融资近日,由特斯拉首席执行官埃隆马斯克创立的隧道初创公司Boringcompany宣布,已在C轮融资中筹集6。75亿美金。VyCapital和红杉资本领投,ValorEquityParvivoS15(12GB256GB5G版)vivoS15vivoS15(12GB256GB5G版)价格暂无价格上市时间2022年屏幕尺寸6。62英寸分辨率24001080屏幕占比91。04HDR技术HDR10输入方式虚拟按为什么手机耗电量过大?很有可能出现了这种问题如今很多手机耗电量都比较大,所以很多时候大家都非常关注电量的问题。如今很多应用都承载到手机中,支付社交拍照娱乐,个人的信息都存在手机中。一些用心不良的人用各种方法来盗取个人信息,比小米手机目前为止推荐购买小米10S不接受反驳小米10s这款机型发布了一年多!为什么我还要强烈推荐这款手机?推荐原因一小米10S这款手机采用了高通骁龙870处理LPDDR5UFS3。0的性能组合,跑分成绩高达69万分上下,属于苹果发布召回计划,这款设备被召回记得去年苹果就对iPhone12启动了召回计划,然而现在苹果又发布了新一轮召回计划,而这次召回的对象却是AppleWatchSerles6设备。根据官网显示,有极少部分40毫米款的马斯克力推收购推特计划宣称已准备好收购资金据美联社纽约4月21日报道,埃隆马斯克说,他已经准备好了用于收购推特公司的465亿美元融资,从而向该公司董事会施加压力,要求其商谈一项收购协议。上周,马斯克曾宣布愿以每股54。20苹果计划下调iPhone12价格,售价或将跌破4000据坊间消息,在苹果秋季发布会发售iPhone14后,iPhone12及mini将会再次降价,双双冲击3000的价位段,而iPhone11系列可能会停产,大踏步迈入5G时代。消息称i
金九银十,东风日产启辰大V正式上市,售价由9。98万起至12。8万新车新闻启辰是东风日产旗下的子品牌,国庆期间,东风日产启辰的首款年轻潮力量SUV启程大V,正式在深圳国际车展上登陆,这款全新的SUV基于启辰VSA创世架构打造,外形由中国本土90后在新生代95后00后生活在最美好的时代,大叔也是这个时代的幸运儿我心里很高兴祖国的新生代生活在最幸福的时代,国泰民安,全民团结,国力蒸蒸日上,朝着中华民族伟大复兴道路稳步前行。大家的收入逐渐增加,对豪华汽车的需求越来越旺盛,作为最早进入中国市场煤炭有色跌落,消费医药抬头!结构行情如何把握机会?作者微信公众号老孟的投资分析圈涨跌就在一瞬间,大家之前看好的煤炭有色,已经开始跌落而之前低迷的消费医药,则抬头上涨了。很多追高小白的信仰又开始接受考验了,这就是投资的现实,当很多人这款荣耀手机为啥不被推荐?价格不降反涨从3月开始,荣耀已成为最活跃的手机品牌。几乎每个月都会发布1或2部手机,完美展示了机海战术的力量。尽管其中有很多俄罗斯套娃产品,但大多数都具有良好的性能,但是随着时间的流逝,某些型游戏党购机推荐,顶级性能,亲民价格,还有宝马联名款随着手机性能的提高,手机游戏的画面质量也在日益提高,手机游戏画面质量的提高反过来又促进了手机的性能需求。对于手机游戏玩家来说,手机的配置不仅代表了它能开启的图像质量有多高,也决定着商用大型洗碗机的特点商用洗碗机的类型主要是大型洗碗机。虽然可以解决大型餐馆的洗碗问题,但很多人怀疑这种商用洗碗机系统是否具有与其他类型的系统相同的结构。为什么可以应用洗碗机?特别是那些学校,酒店,企业比亚迪获前三季度新能源汽车销量冠军,车载显示屏用量与尺寸齐升发展新能源汽车是中国从汽车大国迈向汽车强国的必由之路,也是未来中国汽车走向世界,在汽车领域实现弯道超车的重要一环。来到新能源汽车趋势发展不可逆的时代,可以看到很多自主品牌汽车正在快相机能甩手机几条高速公路?最近一次去南京眼,晚上8点半左右,灯火辉煌的。带着相机(索尼7RIV),也用手机(华为Mate30)拍了几张。其实是为了发朋友圈的,后来想起来正好比较一下二者的差异。当时用手机拍出旧皇新战2021年三星note9vs华为p20pro三星note9华为p20pro可以称得上当年国内国外的安卓机皇,昔日旗舰不知今日表现如何?二皇相争,谁又更胜一筹?今天就来对比测评一下。介绍选手,手上三星note9是国行512g版预算不足用户的福音,这款手机搭载目前最强芯片,仅需3099元华为在手机方面的表现相当出色,无论是华为Mate30Pro还是华为P40Pro,它们在设计,性能,拍照,电池续航等方面的表现都相当不错,但是对于大多数人来说,华为Mate30Pro祭出杀手锏!麒麟990后置三摄,荣耀再次用降价让销量疯狂当一部手机真正引起我们消费者的兴趣时,这是事实。不管是什么,它都无法消除购买欲望。这是一种疯狂盲目的,所以老师一直在谈论手机。这主要是基于疯狂背后的明智态度,它可以略微减少进犯的机