排序算法
排序算法
一、简介
sort排序是计算机中重要的一种操作,作用是讲一个数据元素重新排列成一个有序的序列。排序算法在数据结构中相当重要。
二、算法复杂度
1.时间复杂度
时间复杂度指执行算法所需要的计算工作量:
1)时间复杂度可以认为是对排序数据的总的操作次数、反应的是当n变化时,操作呈现什么规律。
2)常见的时间复杂度有:常数阶O(1),对数阶O(log 2 n),线性阶O(n),线性对数阶O n(log 2 n), 平方阶O(n 2).
3)时间复杂度常数阶O(1)指的是算法中执行为一个常数,则时间复杂度为O(1)
2.空间复杂度
1)空间复杂度是指算法在计算机内执行时所需存储空间的度量,它也是问题规模n的函数。
2)空间复杂度O(1):当一个算法的空间复杂度为一个常量,即不随被处理数据量n的大小而改变时,可表示为O(1)。
3)空间复杂度O(log 2 N):当一个算法的空间复杂度与以2为底的n的对数成正比时,可表示为O(log2n) , ax=N,则x=log a N。
4)空间复杂度O(n):当一个算法的空间复杂度与n成线性比例关系时,可表示为0(n)。
3.排序算法稳定性
假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
稳定性的意义
1、如果只是简单的进行数字的排序,那么稳定性将毫无意义。
2、如果排序的内容仅仅是一个复杂对象的某一个数字属性,那么稳定性依旧将毫无意义
3、如果要排序的内容是一个复杂对象的多个数字属性,但是其原本的初始顺序毫无意义,那么稳定性依旧将毫无意义。
4、除非要排序的内容是一个复杂对象的多个数字属性,且其原本的初始顺序存在意义,那么我们需要在二次排序的基础上保持原有排序的意义,才需要使用到稳定性的算法,例如要排序的内容是一组原本按照价格高低排序的对象,如今需要按照销量高低排序,使用稳定性算法,可以使得想同销量的对象依旧保持着价格高低的排序展现,只有销量不同的才会重新排序。
三、常见算法
冒泡排序
1、简介:
重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来
2、步骤:
1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。 2.对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。 3.针对所有的元素重复以上的步骤,除了最后一个。 4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较
/** * 冒泡排序 */ public static void bubblesSort(int[] val){ boolean flag; for (int i = 0; i < val.length-1; i++) { for (int j = 0; j < val.length-i-1; j++) { if(val[j]>val[j+1]){ int a=val[j]; val[j]=val[j+1]; val[j+1]=a; } } } }
选择排序
1.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
2.再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
3.重复第二步,直到所有元素均排序完毕
public static void bubblesSort(int[] val){ for (int i = 0; i < val.length; i++) { for (int j = i+1; j <val.length; j++) { if(val[i]<val[j]){ int b; b=val[i]; val[i]=val[j]; val[j]=b; } } } }
插入算法
1、简介:
插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。
2、步骤:
从第一个元素开始,该元素可以认为已经被排序
取出下一个元素,在已经排序的元素序列中从后向前扫描
如果该元素(已排序)大于新元素,将该元素移到下一位置
重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
将新元素插入到下一位置中
重复步骤2~5
/** * 插叙算法 * @param val */ public static void insertSort(int[] val){ for (int i = 1; i < val.length; i++) { int get_last=val[i]; int j=i-1; while (j>=0 && get_last<val[j]){ val[j+1]=val[j]; j--; } val[j+1]=get_last; } }
归并排序
1、简介:
将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
2、步骤:
把长度为n的输入序列分成两个长度为n/2的子序列。
对这两个子序列分别采用归并排序。
将两个排序好的子序列合并成一个最终的排序序列
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?