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