sort

排序总结

一、影响排序的因素

·比较次数

·移动次数

·辅助空间

·稳定性

·数据量

·排序对象:基本数据类型、复杂数据类型(基于复杂类型中的某一性质来排序,涉及到排序后的稳定性问题)

·优化排序算法的性能

选择哪一种排序算法,或者说是排序算法的应用范围,当然是能让它发挥最佳性能,有时可多个排序算法联合起来用。


二、桶排序(也叫邮件收发室排序)

·定义:假设有n个取值范围为1至m的元素。我们为它分配m个桶,然后对每个i,根据xi的值,将xi放入相应的桶中去。最后按序扫描每个桶,并把桶中的元素收集起来。

·缺点:

a.如果取值范围很大,需要的桶很多

b.每只桶里面只装相同的元素,桶的使用率不高,可以装同一类数据,已减少数据范围

c.要多少桶,事先是不确定的;不管数据量多大,能否桶的数量是固定的,也就是桶是常量


三、基数排序

桶排序面对数据范围很大效率低的原因是需要的桶很多,且在一次桶操作后不能减少数据范围。那么我们能否让桶为常量,又能减少数据范围。

所以要找一种好的映射方法,而不是根据取值范围来映射。这就是基数排序

实现基数排序的两种方式:从左到右处理,从右往左处理。

四、插入排序

·让我们换另外一种方式:假设知道如何对n-1个数进行排序。现在给定n个数,先对前n-1个数排序,然后通过扫描已排序的n-1个数来确定第n个数的位置,移动数据,把第n个数插入进去。(体育课上迟到,我们经常这样做)

·性能:

比较次数:最坏情况下,要找为n找到一个合适的位置,不得不进行n-1次比较,所以算法复杂度为n2

移动次数:最坏情况下,第n步有可能移动n-1个数,复杂度为n2

·改进:

有没有办法改进比较次数。(如果像体育课那样,我们知道在谁旁边,直接站进去就行。)

由于前面的数有序,我们不用一一比较,可用二分查找,降低比较次数。

·总结:在使用插入排序时,由于最坏情况下的移动次数没有改变,但我们能改变移动次数,所以插入排序不适用于递增或递减的情况。

五、选择排序

·前奏:上面我们改进了插入排序的移动次数,现在来考虑如何改进最坏情况下的移动次数。什么情况下,移动次数最少?那就是不需要移动,假设我们知道该元素的最终 位置,下面该怎么做?

·归纳:精心挑选第n个数,还可以对上面的的直接归纳进一步改进。例如,可以把最大数选做第n个数。选最大数是因为我们知道它应该被放在哪个位置上。下面要做的是,从剩余的数中找出最大数,然后放到合适的位置上。这样就改进了移动次数

·性能:选择排序仅在数据移动上优于插入排序

·改进:能否同时改进比较和移动次数

现在选择一个确定的位置,我们有了logn的比较次数;在数据移动上,我们直接把改数放到最合适的位置。假设把两者结合起来呢。现在考虑前面的数据有序,我们用logn次比较找到合适位置,接下来思考如何插入,使得数据不需要移动。

现在问题变为,如何组织已排序好的数据,使得插入第n个数时不需要移动数据或使得移动量最小。可以使用平衡树来提高插入选择的性能。如AVL树,但需要额外的指针来记录数据。


六、归并排序(分之思想)

·前奏:为了提高插入排序的性能,我们注意到在找到某个合适的位置时,假设接下来要插入的数能够利用前面一个数的信息,那么就不用扫描整个有序列来确定第二的待插入的数的位置。那么待插入的数应当具备什么样的关系(为了能这样做,是有代价的)就可以利用前面已经插入的数来确定自己的位置。所以,当待插入的数有序时,我们可以利用前面插入的数的位置信息,第二个直接从插入位置的后面继续找到合适的位置,从而前面的就不用比较了。这就是归并排序,每次处理多个数据。

·性能:数据比较和移动复杂度都为nlogn

·缺点:

需要临时数组,反复归并,把小的有序列在归并为大得有序列,所以元素的最终位置只有在最后一次归并后才能确定。


七、快速排序

·前奏:为了对归并排序进行改进,找到一种好的分治方法使得每个数的最终位置时确定的。

我们来考虑归并排序为什么需要临时数组,临时数组用来干什么?用来记录临时顺序。

假设我们在一次划分之后能确定该元素的位置。

·归纳:假设知道某个数x满足:x前面的数都小于等于x,x后面的数都大于等于x,这样划分需要n-1次比较,接下来要处理的范围减半。

·性能:不需要额外空间,复杂度受pivot的影响,最坏情况下为n2

·缺点:无法估计性能


八、堆排序

·前奏:我们能否找到一种规则,使得快数排序的pivot是确定的。理想的快排有点像一颗树,根的左子树是pivot左边的数据,右子树是pivot右边的数据。

·归纳:建堆的两种方式

a.自顶向下:数组[1…i]是堆

b.自低向上:数组[i+1….n]代表的所有树都满足堆的性质

·总结:按不同的顺序归纳会得到更好的算法。


九、排序问题的下届(待续)



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值