希尔排序
将数据分成m列,逐列进行排序(采用插入排序)。
先分成8列进行排序,然后是4,2,1
下面展示一些 内联代码片
。
package com.sortAlgorithm;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class ShellSort<E extends Comparable<E>> extends Sort<E> {
@Override
protected void sort() {
List<Integer> stepSequence = shellStepSequence();
//List<Integer> stepSequence = sedgewickStepSequence();
for (Integer step : stepSequence) {
sort(step);
}
}
/**
* 分成 step 列进行排序
* @param step
*/
private void sort(int step) {
//col:第几列, column的简称
for (int col = 0; col < array.length; col++) {//对第col进行排序
//col、col+step、col+2*step、col+3*step、
for(int begin = col + step; begin < array.length; begin += step) {
int cur = begin;
while(cur > col && cmp(cur, cur - step) < 0) {
swap(cur, cur - step);
cur -= step;
}
}
}
}
//希尔本人给出的步长序列,最坏情况时间复杂度是O(n^2)
private List<Integer> shellStepSequence(){
List<Integer> stepSequence = new ArrayList<>();
int step = array.length;
while ((step >>= 1) > 0) {
stepSequence.add(step);
}
return stepSequence;
}
//Robert Sedgewick 给出的步长序列最坏情况时间复杂度是O(n^4/3),是目前已知的最好的步长序列
private List<Integer> sedgewickStepSequence(){
List<Integer> stepSequence = new LinkedList<>();
int k = 0, step = 0;
while (true) {
if (k % 2 == 0) {
int pow = (int) Math.pow(2, k >> 1);
step = 1 + 9 * (pow * pow - pow);
}else {
int pow1 = (int) Math.pow(2, (k - 1) >> 1);
int pow2 = (int) Math.pow(2, (k + 1) >>1);
step = 1 + 8 * pow1 * pow2 - 6 * pow2;
}
if(step >= array.length) break;
stepSequence.add(0,step);
k++;
}
return stepSequence;
}
}