排序算法-希尔排序
排序算法-希尔排序
问题引入
插入排序中存在的问题:
若数据为 2 3 4 5 6 1,则后移的次数明显增多,很影响效率
希尔排序基本介绍
希尔排序是 希尔(Donald Shell) 于1959年提出的一种排序算法。希尔排序也是一种插入排序,他是简单插入排序改进之后的一个更高效的版本,也称为缩小增量排序。
基本思想
- 希尔排序是把记录按下标的一定增量分组
- 对每组使用直接插入排序算法排序
- 随着增量逐渐减少,每组包含的关键词越来越多
代码实现(交换式)
package cn.imut.sort;
import java.util.Arrays;
public class ShellSort {
public static void main(String[] args) {
int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};
shellSort(arr);
}
public static void shellSort(int[] arr) {
int temp = 0;
int count = 0;
for(int gap = arr.length / 2; gap > 0; gap /= 2) {
for(int i = gap; i < arr.length; i++) {
//遍历各组中所有的元素(共gap组,每组有的元素,步长gap)
for(int j = i - gap; j >= 0; j -= gap) {
//如果当前元素大于加上步长后的那个元素,说明交换
if(arr[j] > arr[j + gap]) {
temp = arr[j];
arr[j] = arr[j + gap];
arr[j + gap] = temp;
}
}
}
}
System.out.println("希尔排序第" + (++count) + "轮 =" + Arrays.toString(arr));
}
}
速度测试(80000个数据)
public static void main(String[] args) {
int[] arr = new int[80000];
for(int i = 0; i < 80000; i++) {
arr[i] = (int)(Math.random() * 8000000); //生成一个[0, 8000000)的数
}
Date date1 = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date1Str = simpleDateFormat.format(date1);
System.out.println("排序前的时间是 :" + date1Str);
shellSort(arr);
Date date2 = new Date();
String date2Str = simpleDateFormat.format(date2);
System.out.println("排序后的时间是 :" + date2Str);
}
结论:需要8秒
what???
插入排序只需1秒,希尔排序需要8秒???
因此得出结论,上述代码仅仅为思想上理解的希尔排序!
改进的希尔排序(移位法)
代码如下
public static void shellSort2(int[] arr) {
for(int gap = arr.length / 2; gap > 0; gap /= 2) {
//从第gap个元素,逐个插入
for(int i = gap; i < arr.length; i++) {
int j = i;
int temp = arr[j];
if(arr[j] < arr[j - gap]) {
while (j - gap >= 0 && temp < arr[j - gap]) {
//移动
arr[j] = arr[j - gap];
j -= gap;
}
//退出时,便找到
arr[j] = temp;
}
}
}
}
结论:这才是希尔排序该有的样子,不到一秒,比冒泡、选择、插入都快



浙公网安备 33010602011771号