Java基础知识强化57:经典排序之希尔排序(ShellSort)
2015-09-24 11:01
681 查看
1. 希尔排序的原理:
在上面这幅图中:
初始时,有一个大小为 10 的无序序列。
在第一趟排序中,我们不妨设 gap1 = N / 2 = 5,即相隔距离为 5 的元素组成一组,可以分为 5 组。
接下来,按照直接插入排序的方法对每个组进行排序。
在第二趟排序中,我们把上次的 gap 缩小一半,即 gap2 = gap1 / 2 = 2 (取整数)。这样每相隔距离为 2 的元素组成一组,可以分为 2 组。
按照直接插入排序的方法对每个组进行排序。
在第三趟排序中,再次把 gap 缩小一半,即gap3 = gap2 / 2 = 1。 这样相隔距离为 1 的元素组成一组,即只有一组。
按照直接插入排序的方法对每个组进行排序。此时,排序已经结束。
需要注意一下的是,图中有两个相等数值的元素 5 和 5 。我们可以清楚的看到,在排序过程中,两个元素位置交换了。
所以,希尔排序是不稳定的算法。
2. 希尔排序代码实现:
在上面这幅图中:
初始时,有一个大小为 10 的无序序列。
在第一趟排序中,我们不妨设 gap1 = N / 2 = 5,即相隔距离为 5 的元素组成一组,可以分为 5 组。
接下来,按照直接插入排序的方法对每个组进行排序。
在第二趟排序中,我们把上次的 gap 缩小一半,即 gap2 = gap1 / 2 = 2 (取整数)。这样每相隔距离为 2 的元素组成一组,可以分为 2 组。
按照直接插入排序的方法对每个组进行排序。
在第三趟排序中,再次把 gap 缩小一半,即gap3 = gap2 / 2 = 1。 这样相隔距离为 1 的元素组成一组,即只有一组。
按照直接插入排序的方法对每个组进行排序。此时,排序已经结束。
需要注意一下的是,图中有两个相等数值的元素 5 和 5 。我们可以清楚的看到,在排序过程中,两个元素位置交换了。
所以,希尔排序是不稳定的算法。
2. 希尔排序代码实现:
package cn.itcast; /* * 希尔排序:先取一个小于n的整数d1作为第一个增量, * 把文件的全部记录分成(n除以d1)个组。所有距离为d1的倍数的记录放在同一个组中。 * 先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序, * 直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。 */ public class ShellSort { public static void sort(int[] data) { for (int i = data.length / 2; i > 2; i /= 2) { for (int j = 0; j < i; j++) { insertSort(data, j, i); } } insertSort(data, 0, 1); } /** * @param data * @param j * @param i */ private static void insertSort(int[] data, int start, int inc) { for (int i = start + inc; i < data.length; i += inc) { for (int j = i; (j >= inc) && (data[j] < data[j - inc]); j -= inc) { swap(data, j, j - inc); } } } /* * 交换数组中的两个元素 */ public static void swap(int[] data, int i, int j) { int temp = data[i]; data[i] = data[j]; data[j] = temp; } } /* * 属于插入类排序,是将整个无序列分割成若干小的子序列分别进行插入排序 * 排序过程:先取一个正整数d1<n,把所有序号相隔d1的数组元素放一组, * 组内进行直接插入排序;然后取d2<d1,重复上述分组和排序操作;直至di=1, 即所有记录放进一个组中排序为止 * 初始:d=5 49 38 65 97 76 13 27 49 55 04 * 49 13 |-------------------| * 38 27 |-------------------| * 65 49 |-------------------| * 97 55 |-------------------| * 76 04 |-------------------| * 一趟结果 13 27 49 55 04 49 38 65 97 76 * d=3 13 27 49 55 04 49 38 65 97 76 * 13 55 38 76 |------------|------------|------------| * 27 04 65 |------------|------------| * 49 49 97 |------------|------------| * 二趟结果 13 04 49* 38 27 49 55 65 97 76 * d=1 13 04 49 38 27 49 55 65 97 76 * |----|----|----|----|----|----|----|----|----| 三趟结果 * 04 13 27 38 49 49 55 65 76 97 */
相关文章推荐
- shell脚本报错 /bin/bash^M: bad interpreter
- C程序员学bash shell容易掉坑的注意点(未完待续)
- shell tee
- ubuntu让bash文件可以双击运行
- linux脚本:shell, 判断输入参数的个数(命令行)
- liunx的学习笔记——shell script
- 正则表达式与shell通配符
- Shell脚本入门
- Powershell DSC 5.0 - Pull 模式 (SMB)
- shell 监控局域网的主机是否up(转)
- Bash 脚本编写与sed,awk使用
- linux学习之shell基础篇
- shell中$0,$?,$!等的特殊用法
- Linux 学习作业:认识bash shell
- ubuntu下source、sh、bash、./执行脚本的区别
- Linux复习笔记(一) -- Bash的基本操作
- shell 解释器
- shell第一个例子清理日志
- shell数组
- 解决VM中,xshell无法连接22端口