Shell排序又称为渐进增量排序法。
Shell排序算法思想是:先将这个待排记录序列分割成为若干子序列(子数组)分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。
说明:对每个“增量”h进行一次排序成为“一趟希尔排序”。“一趟希尔排序”中包含多次子数组的排序。(这样命名,便于理解注释的内容)
//Shell排序的伪代码
//把data分成h个数组
// for i =1 to h
// 排序子数组data(i);
// 排序数组data
public void Shellsort(Object[] data){
/*
* 声明涉及到的变量,其中
* i表示:Shell排序中的趟数,即:第i趟排序;
* j,k表示:数组元素;
* h表示:增量值;
* hCnt表示:变量值,用于控制每趟排序的次数;
* increment[]表示:每次排序时的增量值的数组。
* */
int i, j, k, h, hCnt, increments[] = new int[20];
//创建一个合适的增量值h
for(h = 1, i = 0; h < data.length; i++){
increments[i] = h;
h = 3*h + 1;
}
//一共进行i趟排序
for(i--; i >= 0; i--){
h = increments[i];
//每趟排序中执行的次数
for(hCnt = h; hCnt < 2*h; hCnt++){
//在每次中进行直接插入排序
for(j = hCnt; j < data.length;){
Comparable tmp = (Comparable)data[j];
k = j;
while (k-h >=0 && tmp.compareTo(data[k-h]) < 0) {
data[k] = data[k-h];
k -= h;
}
data[k] = tmp;
j += h;
}
}
}
}
注:一般情况下,最后一次排序采用“冒泡排序”,其他排序采用“直接插入排序法”。另外,还有使用混合排序的情况。
Shell排序的时间复杂度在O(N3/2)~O(n7/6)之间,它属于不稳定的排序方法。