希尔排序
1959年由唐纳德·希尔(Donald Shell)提出希尔排序。
希尔排序的思想:把数组中的元素看作是一个矩阵,分成m列,逐列进行排序(一般采用插入排序),m从某个整数逐渐减为1,当m为1时,整个序列将完全有序。因此,希尔排序也被称为递减增量排序(Diminishing Increment Sort)。
矩阵的列数取决于步长序列(step sequence),比如,如果步长序列为{1,5,19,41,109,…},就代表依次分成109列、41列、19列、5列、1列进行排序。不同的步长序列,执行效率也不同。
该方法实质上是一种分组插入方法
来个🌰
希尔本人给出的步长序列是n/2^k(其中n为数组长度),例如要对下面的数组进行排序,n为16,步长序列是{1, 2, 4, 8}:
图片:
首先分成8列进行排序:
然后再分成4列进行排序:
再分成2列进行排序:
最后分成一列进行排序:
最后数组中的元素就变成有序的了。//哈哈哈 看到恼火是不是 我也恼火 哈哈哈哈哈
看看这个~♨️一下 好困zzzzzz
看不懂这篇? 正常 我也看不懂 哈哈哈哈哈哈哈哈哈!
看看这篇希尔或者这篇(大佬果然不一样)😄😄😄
总有和你胃口的~
具体实现
import edu.princeton.cs.algs4.*;
import java.io.*;
public class shell {
private shell() { }
public static void sort(Comparable[] a) {
int n = a.length;
// 3x+1 increment sequence: 1, 4, 13, 40, 121, 364, 1093, ...
int h = 1;
while (h < n/3) h = 3*h + 1;
while (h >= 1) {
// h-sort the array
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);
}
}
assert isHsorted(a, h);
h /= 3;
}
assert isSorted(a);
}
// is v < w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
private static boolean isSorted(Comparable[] a) {
for (int i = 1; i < a.length; i++)
if (less(a[i], a[i-1])) return false;
return true;
}
// is the array h-sorted?
private static boolean isHsorted(Comparable[] a, int h) {
for (int i = h; i < a.length; i++)
if (less(a[i], a[i-h])) return false;
return true;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}
public static void main(String[] args) {
String[] a =StdIn.readAllStrings();
shell.sort(a);
show(a);
}
}