担忧这篇文章介绍的仍然是排序,这次介绍的排序算法是希尔排序,在我看来,希尔排序是一种比较特殊的插入排序,为什么这么说呢,因为在希尔排序过程中运用了插入排序,但又不完全是插入排序的思想。
希尔排序算法步骤
希尔排序实质上是采用分组插入的方法,先将整个待排序记录序列分割成几组,从而减少参与直接插入排序的数据量,对每组分别进行直接插入排序,然后增加每组的数据量,重新分组。这样当经过几次分组排序后,整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。
接下来介绍一下希尔排序的具体步骤,我以关键字序列49,38,65,97,13,27,49,50,04来演示希尔排序的具体过程。
如果对希尔排序的步骤不太理解,可以看下面的代码,希尔排序算法排序的代码有两种,一个是自己设计的增量,另一个是总长度除2,直至为零,下面介绍的是这两种不同方法的代码
void sort(int *str,int m,int r){ //对str进行一次增量为m的希尔排序
int i,j,k,t;//t用来存储待比较值
for(i=m;i<r;i++){
for(j=m;j<r;j=j+m){
t=str[j];
for(k=j-m;k>=0;k=k-m){
if(t<str[k])
str[k+m]=str[k];
else
break;
}
str[k+m]=t;
}
}
}
void ShellSort(int *str,int *arr,int t){//str存储的是待排序数据
//arr存储的是自定义增量,t表示arr的长度
int n=sizeof(str)/4;//计算str的长度
for(int i=0;i<t;i++){ //对str进行t-1趟希尔排序
sort(str,arr[i],n); //对增量为arr[i]进行一次希尔排序
}
}
void sort(int *str,int n){ //表示数组str中的长度
int grap,i,j,t;//grap表示增量,t用于存储值
grap=n/2;
for(grap=n/2;grap>0;grap=grap/2){
for(i=grap;i<n;i++){
t=str[i];
for(j=i-grap;j>=0;j=j-grap){
if(t<str[j])
str[j+grap]=str[j];
else
break;
}
str[j+grap]=t;
}
}
}
希尔排序算法的特点
1、记录跳跃式地移动导致排序方法是不稳定的。
2、只能用于顺序结构,不能用于链式结构。
3、增量序列可以有各种取法,但应该使增量序列中的值没有除一之外的公因子,并且最后一个增量必须是0。
3、记录总的比较次数和移动次数都比直接插入排序的要少,n越大时,效果越明显。所以适合初始记录无序,n较大的情况。
到这里对希尔排序的介绍就结束了,谢谢大家,欢迎大家多多指教。