高级算法设计与分析 学习笔记 2 希尔排序 线性时间内的排序——计数排序,基数排序,桶排序

希尔排序(比较排序)

要选定一个步长(比如4),那么0,4,8……它们是一组,1,5,9……他们是一组。分组排完之后再换成2步长,最后改成1,就行了。

实际使用时一般先设置步长为n/2,然后n/4……

组内排序直接插入就可以了。

只要是比较排序,不可能好过nlgn。

这一点可以使用决策树来证明:

可以看到,每个叶子代表一种排序结果,一共有n!个。

线性时间内的排序算法(非比较排序)

这种算法就不能弄比较了。要用空间换时间。

计数排序

算法流程

举个例子:

第一步:遍历整个数组,记录每种数据各自出现了几次。

第二步:看到C组,从第一个元素开始加上上一个元素的值,这样就记录了这个位置对应的元素在数组中排老几。

第三步:从最后一个数开始,先看看C,检查一下自己应该排哪一位,填进去。同时C组中对应数字要减一(这样的话,假如有一样的数,直接会填到前一位)

最后就是这样,从后到前遍历一遍就行。

为什么要从后到前?因为这样就是稳定的算法了。原本在前面的还在前面,不然就会搞反。

计数排序的缺点

显然,C的长度会受到A中最大元素K的影响,要是K特别大,那就完蛋了。

基数排序

算法流程

就是把数分成一位一位的,分别按照个位,十位,百位这样比较,比完就OK了。显然这样的算法不用太担心K很大。

最好从低位排起,还要用稳定的排序,这样一来这种算法也是稳定的了。

性能分析

这里的分析中,每一倘的排序是计数排序。可以看到基数排序就是对计数排序的改良,针对的就是计数排序K太大的问题。把数字分成很多块,这样每一趟用计数排序只有O(n+k)的复杂度(K就是2^r,这里r是指二进制数的位数,这里的使用场景是二进制数比较),最后乘以趟数b/r就行。

桶排序

算法流程

根据开头的一位放到对应链表里,每往表里加一个数用的方法是插入排序(例如23会插到21和26中间)最后再穿起来。可以看到这些数分布的越均匀越好,要是全都是一个数开头那就成插入排序了。要是足够均匀,那就是标准的线性时间内的排序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值