一、简介
希尔排序是基于直接插入排序的以下两点性质而提出的改进方法:
1.插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
2.插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。
二、原理
希尔排序是将待排序的数组元素 按下标的一定增量分组 ,分成多个子序列,然后对各个子序列进行直接插入排序算法排序;然后依次缩减增量再进行排序,直到增量为1时,进行最后一次直接插入排序,排序结束。
希尔排序:例如间隔是3,每3个进行一个插入排序,希尔排序会减少间隔在进行排序,最后间隔缩小为1
三.图解
四、时间复杂度
**希尔排序的执行时间依赖于增量序列。 **
希尔排序耗时的操作有:比较 + 后移赋值。
时间复杂度情况如下:(n指待排序序列长度)
- 最好情况:序列是正序排列,在这种情况下,需要进行的比较操作需(n-1)次。后移赋值操作为0次。即O(n)
- 最坏情况:O(nlog2n)。
- 渐进时间复杂度(平均时间复杂度):O(nlog2n)
五.代码:
ShellSort
package ch08;
/**
* 希尔排序
*
* @author Administrator
*
*/
public class ShellSort {
/**
* 排序方法
*/
public static void sort(long[] arr) {
//初始化一个间隔
int h = 1;
//计算最大间隔
while(h < arr.length / 3) {
h = h * 3 + 1;
}
while(h > 0) {
//进行插入排序
long tmp = 0;
for(int i = h; i < arr.length; i++) {
tmp = arr[i];
int j = i;
while(j > h - 1 && arr[j - h] >= tmp) {
arr[j] = arr[j - h];
j -= h;
}
arr[j] = tmp;
}
//减小间隔
h = (h - 1) / 3;
}
}
}
测试类:
package ch08;
import ch02.InsertSort;
public class TestShellSort {
public static void main(String[] args) {
long[] arr = new long[10];
arr[0] = 90;
arr[1] = 12;
arr[2] = 23;
arr[3] = 15;
arr[4] = -4;
arr[5] = 1;
arr[6] = 97;
arr[7] = 4;
arr[8] = 3;
arr[9] = 8;
System.out.print("[");
for(long num : arr) {
System.out.print(num + " ");
}
System.out.print("]");
System.out.println();
ShellSort.sort(arr);
System.out.print("[");
for(long num : arr) {
System.out.print(num + " ");
}
System.out.print("]");
System.out.println();
}
}
运行结果: