2012-12-16 工作日志
2012-12-16 23:19
141 查看
Shell排序
Shell排序可以理解为插入排序的变种,它充分利用了插入排序的两个特点:
1)当数据规模小的时候非常高效
2)当给定数据已经有序时的时间代价为O(N)
所以,Shell排序每次把数据分成若个小块,来使用插入排序,而且之后在这若个小块排好序的情况下把它们合成大一点的小块,继续使用插入排序,不停的合并小块,知道最后成一个块,并使用插入排序。
这里每次分成若干小块是通过“增量” 来控制的,开始时增量交大,接近N/2,从而使得分割出来接近N/2个小块,逐渐的减小“增量“最终到减小到1。
一直较好的增量序列是2^k-1,2^(k-1)-1,.....7,3,1,这样可使Shell排序时间复杂度达到O(N^1.5)
Shell排序可以理解为插入排序的变种,它充分利用了插入排序的两个特点:
1)当数据规模小的时候非常高效
2)当给定数据已经有序时的时间代价为O(N)
所以,Shell排序每次把数据分成若个小块,来使用插入排序,而且之后在这若个小块排好序的情况下把它们合成大一点的小块,继续使用插入排序,不停的合并小块,知道最后成一个块,并使用插入排序。
这里每次分成若干小块是通过“增量” 来控制的,开始时增量交大,接近N/2,从而使得分割出来接近N/2个小块,逐渐的减小“增量“最终到减小到1。
一直较好的增量序列是2^k-1,2^(k-1)-1,.....7,3,1,这样可使Shell排序时间复杂度达到O(N^1.5)
package algorithms.sort; import algorithms.AbstractSort; public class ShellSort extends AbstractSort { @Override public void sort(int[] array) { int len = array.length; int value = 1; while ((value + 1) * 2 < len) { value = (value + 1) * 2 - 1; } for (int delta = value; delta >= 1; delta = (delta + 1) / 2 - 1) { for (int i = 0; i < delta; i++) { modifyInsertSort(array, i, len - i, delta); } } } private void modifyInsertSort(int[] array, int from, int len, int delta) { if (len <= 1) { return; } int tmp = 0; for (int i = from + delta; i < from + len; i += delta) { tmp = array[i]; int j = i; for (; j > from; j-=delta) { if (tmp - array[j-delta] < 0) { array[j] = array[j - delta]; } else { break; } } array[j] = tmp; } } }
相关文章推荐
- 3月6日工作日志-88250
- 2009-05-10工作日志
- 3月8日工作日志-88250
- 2006.10.14工作日志
- log4j日志记录级别是如何工作?
- 12.1工作日志
- 工作日志2016-5-6
- 互联网金融项目——工作日志(三)之工具类
- 工作日志2014-07-07
- 我的工作日志4
- 2017-10月工作日志
- 关于MSSQL的一篇工作日志(青鸟日志)
- 2010-06-02工作日志
- 2015-8-11工作日志
- 20130516_工作日志_charger
- 内存数据库内核开发 工作日志(innodb的原理,算法详细剖析)(九)
- 工作日志2007.01.04
- 外企工作日志4
- 【小平工作日志】Spring配置文件中<context:annotation-config/>详解!
- 外企工作日志13