希尔排序算法

来源:互联网 发布:瓷砖上铺木地板 知乎 编辑:程序博客网 时间:2024/05/17 22:10
思想简单描述:

在直接插入排序算法中,每次插入一个数,使有序序列只增加1个节点,并且对插入下一个数没有提供任何帮助。如果比较

相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比较就可能消除多个元素交换。D.L.shell于

1959年在以他名字命名的排序算法中实现了这一思想。算法先将要排序的一组数按某个增量d分成若干组,每组中记录的

下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。当增量减到1时,整个

要排序的数被分成一组,排序完成。下面有几种用C语言实现的方法:

方法一:

严格按照定义来实现的算法

void ShellSort1(int *array, int len){int i, j, grap, k, tmp;for(grap=len/2; grap>0; grap/=2)//步长{for(i=0; i<grap; i++)//直接插入排序{for(j=i+grap; j<len; j+=grap){if (array[j]<array[j-grap]){tmp = array[j];k = j-grap;while(k>=0 && array[k]>tmp){array[k+grap] = array[k];k -= grap;}array[k+grap] = tmp;}}}}}
方法二:代码量太大了,不够简洁清晰。因此进行下改进和优化

void ShellSort2(int *array, int len){int i,j,grap,tmp,k;for(grap=len/2; grap>0; grap /=2){for(j=grap; j<len; j++)<span><span class="comment">//从数组第gap个元素开始</span></span>{if (array[j]<array[j-grap])<span><span class="comment">//每个元素与自己组内的数据进行直接插入排序</span><span> </span></span>{tmp = array[j];k = j-grap;while(k>=0 && tmp<array[k]){array[k+grap] = array[k];k = k-grap;}array[k+grap] = tmp;}}}}
方法三:在将以上的代码进行下改进

void ShellSort3(int *array, int len){int i,j,k,tmp;for(k=len/2; k>0; k/=2){for(i=k; i<len; i++){tmp = array[i];for(j=i-k; j>=0 && array[j]>tmp; j-=k){array[j+k] = array[j];}array[j+k] = tmp;}}}
方法四:还可以再次优化:

void ShellSort4(int *array, int len) {int i,j,gap;for(gap=len/2; gap>0; gap/=2){for(i=gap; i<len; i++){for(j=i-gap; j>=0 && array[j]>array[j+gap]; j-=gap){swap(&array[j], &array[j+gap]);}}}}
另一种方法是根据其它论坛上进行整理的,也是比较容易理解一种方法

void ShellSort(int *array, int len){int i,j, tmp, k;k = len/2;/*间距值*/while(k>=1){for(i=k; i<len; i++){tmp = array[i];j = i-k;while(j>=0 && array[j]>tmp){array[j+k] = array[j];j -= k;}array[j+k] = tmp;}k = k/2;/*缩小间距值*/}}
应该还会有更多,更优,更好的实现方法,由于水平有限,不足之处,还请大家多多指正!

0 0