希尔(shell)排序-插入排序的扩展

来源:互联网 发布:弱覆盖定义 优化措施 编辑:程序博客网 时间:2024/05/17 00:05

希尔排序是插入排序的一种扩展和延伸.在希尔排序之前,有必要先说一下插入排序.

插入排序的工作原理:

1.从第2号元素开始扫描,直到最后一个元素.

2.当扫描到i号元素的时候,假定前边0,1,2,3...i-1号元素都已经有序.用挖坑填数的方法,将A[i]号元素从数组中挖出来,保存在key中,依次比较A[i-1],A[i-2]....的值,如果都比key大,则后移,直到找到key的最终元素,就把key填进应在的位置.当扫描完成,数组已经有序.

举个例子:4,7,8,6,9,12.在某一时刻,i指向6,则将j指向i-1,即8.因为8 > 6,则8后挪一位,j继续前移,7 >6,7继续前移,4<6,则4后面的位置就是6应在的位置,于是将6填入这个位置即可.重复以上步骤即可完成排序.

代码:

void InsertSort(int A[],int beg,int end){for(int i=beg+1;i<=end;++i){int key=A[i];int j=i-1;while(j >= beg && A[j] > key){A[j+1]=A[j];--j;}A[j+1]=key;}}
希尔排序实质上是将数组化整为零,先将数组分成n组,对每一组进行插入排序,这里并不像归并排序一样,分开的两组是一前一后,希尔排序分开的元素中间都隔着一定步长step,实质上,步长为多少,就有多少组.例如:3,4,2,6,7,1,如果step=3,则分开的组为{3,6},{4,7},{2,1}.最后逐渐将step递减逼向1,当step=1,则数组已经有序.这个比较容易理解,因为步长为1,说明只有一组,对一组数即使直接用插入排序也能排好序.但是这里用了插入排序的一个很好的性质,那就是,如果数组已经基本有序,那么插入排序的效率非常高,可以达到o(n).

总结:

希尔排序:

1.将数组划分为n组,则步长为n

2对每个组排序.

代码:

#include<iostream>using namespace std;void insertsort(int A[],int beg,int end,int step){for(int i=beg+step;i<=end;i+=step){int key=A[i];int j=i-step;while(j >= beg && A[j] > key){A[j+step]=A[j];j-=step;}A[j+step]=key;}}void shellsort(int A[],int beg,int end){//1.以step分组,步长也为stepfor(int step=(beg+end)/2; step > 0 ; step /=2){//2.对每个组进行排序for(int i=0;i<step;++i)insertsort(A,beg+i,end,step);}}void main(){int A[]={4,6,3,8,9,1,0,24};int len=sizeof(A)/sizeof(A[0]);//insertsort(A,0,len-1);InsertSort(A,0,len-1);//shellsort(A,0,len-1);for(int i=0;i<len;++i)cout<<A[i]<<' ';}




原创粉丝点击