1.前面讲的简单的排序都是连续性的(指每一个元素与其他元素比较都是一个一个的逐一比较的),而哈希尔的排序是跳跃式的( 依靠一个预先设好的增量),基于此,一个元素与其他元素比较时间隔都是h,接着h逐渐缩小,而它又是基于插入排序的,只不过,插入排序每次只与前面的一个元素比较,现在是与前面间隔为h的元素进行比较, 通过每次比较后,缩小h的范围后继续用插入排序进行比较从而达到排序的目的。
基于此:(1)因为要排序的范围是通过h来控制的,所以如何设置通过数学公式或者说设计什么样的函数表达式来得出h的大小就变得格外重要了(这也是他不稳定的地方)一般来说,数据越多,一开始的间隔就要越大(可以通过计算使得间隔一开始是中间 到比较前面的元素的距离,然后不断减小,直至间隔为1,下面展示的十个数据以h间隔为4的希尔排序)
package csnd; public class Arrash { int array[]; int nElems; public Arrash() { nElems=0; } public Arrash(int n) { array = new int[n]; nElems=0; } public void insert(int j) { array[nElems]=j; nElems++;//注意,在这里当最后一个元素插入后,nElems值还会加一 } public void display(){ for(int i=0;i<nElems;i++) System.out.print(array[i]+" "); System.out.println(); } public void shellSort() { int inner,outer; int temp; int h=1; while(h<=nElems/3) h = h*3+1; while(h>0) { for(outer=h;outer<nElems;outer++) { inner = outer; temp = array[outer]; while(inner>h-1&&array[inner-h]>=temp)//不断使数组基本有序直到最后有序 { array[inner]=array[inner-h]; inner -=h; } array[inner] = temp; } h = (h-1)/3; } } public static void main(String[] args) { Arrash theArray = new Arrash(10); for(int i=0;i<10;i++) { int n=(int)(Math.random()*(10)); theArray.insert(n); } System.out.println("排序前的数组"); theArray.display(); System.out.println("排序后的数组"); theArray.shellSort(); theArray.display(); } }
结果:
排序前的数组 6 4 9 2 4 0 1 2 6 1 排序后的数组 0 1 1 2 2 4 4 6 6 9