数据结构——408排序、复杂度记忆

408的小伙伴先为大家送上一个关于排序的记忆口诀:
(本口诀来自于哔站up狂暴的南希,觉得这个方法特别好,在此感谢)

小故事:
很久以前有两个小动物,
插帽龟,统计鸡。他们办事两个很稳!(插冒归,桶计基稳定)
插帽龟在选帽插的时候慌了!(选冒插n2)
插帽龟说你们嗯老实点快归堆(nlogn快归堆)
统计鸡说别着急,我会加减乘除(桶计n+k 基n*k)

精简版:
插冒归 和 桶计基 稳
选冒插 慌了 n2了
快归堆 嗯老 nlogn
统计鸡 加减乘除 桶计n+k 基n*k

代码掌握要求:快速排序(c)

冒泡排序

一句话描述:如同水底的泡泡向上冒一样,愈来愈大。
(升序为例:每趟结束,会将整个序列中 大的元素 放到最后的 正确位置)

具体思想:
从头开始,依次比较相邻两个元素大小,以升序为例,我们每次遍历把当前范围的最大值置尾,遍历(n-1)次后完成排序。

具体操作为,外层套循环,依次遍历,最多需要(n-1)次。每次选中两个相邻元素,如果右>左,则将两元素位置交换,如果正确则不动,那么我们就将较大的元素置后了,依次遍历就实现了最大元素置尾。那么进行最多n-1次后,就实现了整体的排序。

时间复杂度:
还是以升序为例,最好情况就是顺序已经排好了,不用移动,那么我们就没有消耗;最坏情况对于冒泡排序而言,就是整个相反,那么我们每个元素都需要花费一次遍历把它移到队尾,需要移动n-1次。然后我们再进行n-1次遍历,时间复杂度为O(n2)。
冒泡排序

编程实现部分:采用双层for循环。外层循环索引为循环序数,每完成一次循环,便确定一个数的位置(将当前遍历的数组中最大值置于最后)。内层循环指向不同的相邻元素,遍历范围为:n-i-1

例:有10个数,由于最后一次无需移动,则遍历9次即可完成,那么便是

for(int i=0; i<number.length-1; i++)

对于内层:

for(int j=0; j<number.length-i-1; j++)

具体实现可以为:

public class demo {
	public static void main(String[] args) {
		
		int[] number= {10, 8 , 7, 3 , 5 , 2 , 6};
		int tmp=0;
		for(int i=0;i<number.length-1;i++) {
			for(int j=0;j<number.length-i-1;j++) {
				if(number[j]>number[j+1]) {
					tmp=number[j];
					number[j]=number[j+1];
					number[j+1]=tmp;
				}
			}
		}
		for(int x:number) {
			System.out.print(x+"\t");
		}
	}
}

选择排序

一句话描述:遍历所有元素,将遍历过程中最大那个,和最后的元素交换位置。

具体思想:还是以升序为例,冒泡排序是把大的往后放,选择排序是把小的往前放。从头起选一个范围,范围由全表到小,选出当前范围内最小的元素置首(范围的首部),然后缩小范围,将首位剔除,多次遍历,就实现了排序。

设置一个临时最小值位,首先由全表开始,找出最小的元素,放在首位。此时最小值已经位于正确位置,我们不用管它了,将窗口缩小。从第二位开始,找出当前范围的最小值,将它置于当前范围的首位(全表的第二位),那么第二小的数也已经就位,继续遍历,知道完成全表排序。

对于时间复杂度:外层循环,我们需要进行n次范围选取,内层的最小值搜索,我们需要遍历最多n个数,那么时间复杂度为O(n2)。
选择排序

插入排序

具体思想:选取一个范围,范围由小到大,保证范围内排序正确,如同将扩大范围得来的新元素插入到原有序的范围中一样。

具体操作:首先我们选前两个元素,按照所需规则先排序(如升序)。那么我们调整顺序,将两者中较大的元素后置。接下来,选前三个元素进行排序。由于一和二的大小关系已经确定,此时引入第三个元素就相当于插入(所以叫插入排序)。此时就有三种可能,那么就将其与已完成排序的元素逐一比较,如果比二小,再与一进行比较。。由此,逐渐增加到三个、四个、到所有元素,最终得到完成排序的数列。在这个过程中,我们每次的操作都是一种插入,最多需要遍历(n-1)次完成排序。

下面我们来看时间复杂度:
我们需要两层循环,外层循环进行范围的选取,最多需要(n-1)次;内层循环我们从后遍历,找出引入元素要插入的位置,最多需要n次,那么插入排序的时间复杂度为O(n2)。
插入排序

希尔排序

一句话描述:分组思想,组内元素排序,减小划分间隔使组变大,直到间隔为1全部有序。

首先设定一个间隔,事实上希尔排序对于分组的间隔没有明确的界定,不过一般为数据总数的一半。如:10个整型数据,那么便可以设定间隔为5,那么就将所有的数据分成了5组,每组就分配到了两个数据。将这5组进行组内排序,然后,我们再将排好序的所有元素合在一起。此时,整个数组已经有部分数据之间具备顺序关系了,我们接着重新设定间隔,在原有基础上减小间隔,一般为减半,继续对组内的元素进行排序。不断地重复上述操作,直到最后的间隔为1。

此时,我们进行最后一次整体的排序,得到最终结果。

!无论过程中设定的间隔为多少,最终希尔排序的间隔都会为1 !
希尔排序

快速排序

一句话描述:选一个元素,将比他小的元素放他左面,比他大的放右面,一趟下来这个元素的正确位置被找到。
快速排序

归并排序

一句话描述:分组使组内有序,将组进行归并为更大组,使组内有序,直至整体。
归并排序

堆排序

一句话描述:以堆的思想存储,进行堆调整得出最值元素取出,并继续调整。
堆排序

基数排序

一句话描述:从最高位开始(万、千、百),将相同数字的元素放在同一组,按照大小合并构成新序列,重复此操作直到个位。
基数排序

时间复杂度分析

时间复杂度最好最坏平均稳定性
冒泡排序O(n)O(n2)O(n2)稳定
选择排序O(n)O(n2)O(n2)不稳定
插入排序O(n)O(n2)O(n2)稳定
希尔排序O(n)O(n2)O(n1.3)不稳定
快速排序O(n*log2n)O(n2)O(n*log2n)不稳定
归并排序O(n*log2n)O(n*log2n)O(n*log2n)稳定
堆排序O(n*log2n)O(n*log2n)O(n*log2n)不稳定
基数排序O(d(r+n))O(d(r+n))O(d(r+n))稳定

注:r为基数,d为长度,n为个数。

图片整理自网络。
未完待续。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值