希尔排序(Shellsort)的名称源于它的发明者Donald Shell,该算法是冲破二次时间屏障的第一批算法之一。它通过比较相距一定间隔的元素来工作;各趟比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟排序为止。由于这个原因,希尔排序有时也叫做缩小增量排序(diminishing increment sort)。
希尔排序使用一个序列h1,h2,.....ht,叫做增量序列(increment sequence)。只要h1 = 1,任何增量序列都是可行的,不过有些增量序列比另外一些增量序列更好。
在使用增量hk的一趟排序之后,对于每一个i我们有A[i] <= A[i+hk];所有相隔hk的元素都被排序。如图所示:
希尔排序的一个重要性质是:一个hk排序的文件保持它的hk排序性。
增量序列的一种流行(但是不好)的选择是使用Shell建议的序列ht = [N/2]和hk = hk+1/2
#include typedef int ElementType; void ShellSort(ElementType A[], int N){ for(int Increment = N/2; Increment > 0; Increment /= 2){ for(int i = Increment; i < N; ++i){ ElementType tmp = A[i]; int j = i; for(;j >= Increment; j -= Increment){ if(tmp < A[j-Increment]){ A[j] = A[j-Increment]; } else{ break; } } A[j] = tmp; } }}int main(){ int A[] = {81,94, 11, 96, 12, 35, 17, 95, 28, 58, 41, 75, 15}; int size = sizeof(A)/sizeof(int); ShellSort(A, size); for(int i = 0; i < size; ++i){ std::cout << A[i] << " "; } std::cout << std::endl; return 0;}
希尔排序因为增量序列的选择原因,所以是一个算法非常简单又具有机器负责分析的一个好例子。
希尔排序的性能在实践中是完全可以接受的,即使是对于数以万计的N仍是如此。编程的简单特点使得它成为对适度的大量输入数据经常选用的算法。
在实践中最好的序列是{1,5, 19, 41, 109,.....)该序列中的项或者是9×4^i-9×2^i+1,或者是4^i-3*2^i+1。