希尔排序

来源:互联网 发布:妇科医生在线网络咨询 编辑:程序博客网 时间:2024/06/10 07:06

Shell排序:

将整个序列划分成若干子序列,对每个子序列进行直接插入排序。

步骤:

1.产生取值间隔gap,保存到distance数组中。(gap=[gap]/2)

distance[0]=n/2;  //distance 数组初始化

i=1;

While(true)

{

d=distance[i-1]/2;

distance[i]=d;

if(distance[i]==1)break;

i++; 

}

2.每一个gap,确定一个子序列划分方法。

假设有如下数组:


gap应取5、2、1三个数。

(1)gap=5,应形成5个子序列,其中每个子序列包含两个元素:

A[0]A[5]     A[1]A[6]    A[2]A[7]    A[3]A[8]   A[4]A[9]

(2)gap=2,应形成2个子序列,每个子序列包含5个元素:

A[0]A[2]A[4]A[6]A[8]      A[1]A[3]A[5]A[7]A[9]

(3)gap=1,一个子序列:

 A[0]A[1]…A[9]

3.每个gap,需要进行gap个直接插入排序。

即 for(i=0;i<gap;i++)

4.设计单个序列的直接插入排序。


主要程序实现步骤:

for(i=0;i<gap;i++) //gap次直接插入排序

{

//直接插入排序

    for(j=1;j<n/gap;j++) //假设第一个元素有序,扫描其后的待排序元素i个子序列,要扫描n/gap-1

                        //这个子序列中的元素:(A[i]A[i+gap]A[i+2gap]…A[i+(n/gap-1)*gap])

                        //A[i],A[i+j*gap]

{

   if(A[i+j*gap]<A[i+(j-1)*gap])//逆序

   { 

       temp=A[i+j*gap];

 //寻找插入位置     

for(k=0,k<j*gap;k+=gap) //若待排序元素为A[i+j*gap],前面排好序的元素有j.

    if(A[i+j*gap]>A[i+k])

      continue;

    else //插入位置为A[i+k],待排序元素为A[i+j*gap]

{

   for(m=0;m<j-k/gap;m++)  //并移动{[i+j*gap-(i+k)]/gap}个元素

   {

       A[i+(j-m)*gap]=A[i+(j-m-1)*gap]

     

}

   A[i+k]=temp;

 

 

}

  

}

 }/*if*/

   else continue;  //未逆序,继续扫描下一个元素。

 

} 

}


总结:共需5个for循环。分别是从distance数组中提取gap循环,gap子序列循环,剩下的是直接插入排序中的三个循环。即:扫描待排序元素循环,寻找插入位置循环,移动元素循环。

设计循环主要是设定循环的起点、终点和步长。

原创粉丝点击