1.什么是希尔排序
希尔排序的核心思想是使数组中任意间隔为g的元素都是有序的。首先取小于数组长度的一个数g1作为第一个间隔值,对全部数组进行两两分组,在分组内实现排序。然后取g2(g2小于g1,g1到g2应有一个明确的增量算法)再对数组进行两两分组,再实现组内排序。重复上述操作直到gt=1为止,此时数组排序已经完成。
2.为什么使用希尔排序
希尔排序是对插入排序的改进,希尔排序在大数组的排序上数组越大相对于插入排序和选择排序的优势越大。相比较于更高级的排序算法,中等大小的数组排序更适合使用希尔排序,因为它运行时间是尚可接受的,同时代码量小,且不需要额外的储存空间。
3.关于增量和时间复杂度
不难看出,影响希尔排序效率的一大因素就是其增量的选择,目前尚未能从数学上得出“效率最高”的增量,也就是说目前尚未有明确的时间复杂度。通用的时间复杂度为O(n^1.3),最坏情况为O(n^2)。对于绝大多数情况,希尔排序是远快于O(n^2)的排序算法的。
4.代码实现(Java)
public class Shell {
/**
* 比较两者大小
*
* @param v
* @param w
* @return 当v小于w,返回true,反之返回false
*/
private boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
/**
*
* @param array
* 值所在的数组
* @param i
* 排序前靠前的值的下标
* @param j
* 排序前靠后的值的下标
*/
private void exch(Comparable[] array, int i, int j) {
Comparable t = array[i];
array[i] = array[j];
array[j] = t;
}
public void sort(Comparable[] array) {
int size = array.length;
int gap = 1; // 间隔值初始
int dt = 3; // 增量幅度
while (gap < size / dt)
gap = dt * gap + 1;
System.out.println("gap:"+gap);
while (gap >= 1) {
for (int i = gap; i < size; i++) {
for (int j = i; j >= gap && less(array[j], array[j - gap]); j -= gap) {
exch(array, j, j - gap);
}
}
gap = gap / dt;
}
}
}