希尔排序的优点:希尔排序,是效率最高的简单排序的算法了,在很多情况下我们都会很喜欢希尔排序的,因为希尔排序的代码量很小,而且希尔排序并不需要使用额外的内存空间,和更为高效的算法比,只要是我们的N不是特别的大(N是需要排列的元素)我们都会优先考虑希尔排序,因为希尔排序比更加高级的算法相比,排序上的时间是差不多的。尤其是当我们所用的编程语言没有内置的高效的算法的时候,我们就可以优先考虑希尔排序了。
希尔排序的本质:希尔排序是基于插入排序的快速排序的算法,希尔排序为了加快排序速度,所以简单的改进了插入排序,交换不相邻的元素以对数组的局部进行排序,并且最终用插入排序将局部有序的数组排序。
希尔排序的思想:希尔排序的思想是数组中间任意间隔为h的元素都是有序的。这样的数组被我们成为h有序数组。换句话说,一个h有序数组就是h个相互独立的有序数组编织在一起组成的一个数组。在进行排序时,如果h很大,我们就会将元素移动到很远的地方,为实现更小的h有序创造方便。用这种方式,对于任意以1结尾的h序列,我们都能够将数组排序,这就是希尔排序。
希尔排序高效的原因:插入排序中移动元素是移动一个距离,我们的小改动是每次交换元素的时候移动的距离由1改为h了,这样,希尔排序的实现就转换成了一个类似于插入排序,但是使用了不同的增量,希尔排序它权衡了子数组的规模和有序性,在排序之初,各个子数组都很短,排序之后子数组都是部分有序的,最后一句话就是:能够透彻的理解希尔排序的性能至今仍是一项挑战,希尔排序也是我们唯一无法准确描述其对于乱序的数组的性能特征的排序方法。
让我们看一下希尔排序的代码:
public class Shell {
public static void sort(Comparable[] a) {
int N = a.length;
int h = 1;
while (h < N / 3)
h = 3 * h + 1;
while (h >= 1) {
for (int i = h; i < N; i++) {
for (int j = i; j >= h && less(a[j], a[j - h]); j -= h)
exch(a, j, j - h);
}
h = h / 3;
}
}
public static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
private static void exch(Comparable[] a, int i, int j) {
Comparable t = a[i];
a[i] = a[j];
a[j] = t;
}
public static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
System.out.println(a[i] + " ");
System.out.println();
}
}
public static boolean isSorted(Comparable[] a) {
for (int i = 1; i < a.length; i++)
if (less(a[i], a[i - 1]))
return false;
return true;
}
public static void main(String[] args) {
String[] a = "B,D,C,A,E,G,F, ".split(",");
sort(a);
assert isSorted(a);
show(a);
}
}