这篇是介绍一下希尔排序,希尔排序的原理就是在插入排序的基础上进行修改,相比起插入排序的元素移动次数,希尔排序移动次数大大的减少。
希尔排序的原理是将一定间隔的元素进行比较,再进行交换,此举的好处在于若两个元素的距离相差比较远,那可以不用移动许多的元素再进行交换,而是直接进行交换,这就省去了许多的时间开销,由原来插入排序的O(N^2)降到现在的O(N*(logN)^2),时间复杂度大大的减少,虽然没有快速排序快(下一篇讲),但已经是很大的进步了。
现在我们来看看代码:
<span style="font-size:24px;">public class MyArray {
private int nElem;
private long[] theArray;
public MyArray(int s){
theArray = new long[s];
nElem = 0;
}
public void insert(long data){
theArray[nElem] = data;
nElem++;
}
public void displayArray(){
System.out.println("A = ");
for (int i = 0; i < nElem; i++) {
System.out.print(theArray[i] + " ");
}
System.out.println("");
}</span>
这个应该没什么大问题,再来看主要的shellsort()方法:
public void shellSort(){
int inner,outer;
long temp ;
int h = 1;
while(h <= (nElem/3)){ //设置比较间隔
h = h*3+1; //h 为1,4,9。。。
}
while (h>0) {
for (outer = h ; outer < nElem; outer++) { //一个外循环。每次获得间隔,进行循环比较
temp = theArray[outer];
inner = outer;
while (inner>h-1 && theArray[inner-h] > temp) { //内循环,对几个间隔元素进行比较,将大的放在后面
theArray[inner] = theArray[inner - h];
inner -= h;
}
theArray[inner] = temp;
}
h = (h-1)/3;
}
}
要注意这里有两个循环,外循环以及内循环,不能搞错,两个循环在代码中已经有注释,就不再赘述了,需要注意的是对间隔的计算,我们这里使用的间隔是常用间隔,计算公式为h= h*3+1,并且在循环时候,间隔是逐渐减小的,这个大家需要注意一下。
然后是主函数:
public class TestShell {
public static void main(String[] args) {
MyArray myArray = new MyArray(100);
for (int i = 0; i < 10; i++) {
int n = (int) (java.lang.Math.random()*99);
myArray.insert(n);
}
myArray.displayArray();
myArray.shellSort();
myArray.displayArray();
}
}
这个应该没什么问题,然后是运行结果: