希尔排序又叫做递减增量排序。在这种排序中,我们将设置一个步长(增量),我们在比较数据时根据增量去进行比较,这样我们的数据会一次性前进很多步,所以希尔排序的效率要比直接插入排序的效率高。
希尔排序的思想就是我们设置一个步长,然后我们根据这个步长进行划分子序列,得到子序列1,子序列2....,然后我们对每个子序列进行直接插入排序,我们也知道当整个数列基本有序的时候使用直接插入排序的效率是非常高的。然后我们缩小步长,则我们划分的子序列的个数越来越少,我们每个子序列中的数据越来越多,则我们基本有序的数据就越来越多,直到我们的增量为1时,我们对整个已经基本有序的序列采用一次直接插入排序,则我们的排序结束。
还是按照往常的习惯,给出图示
好了,下面直接给出代码,代码里面都有详细的注释。
1 #include <stdio.h> 2 3 void shellsort(int *arr[],int length); 4 5 int main(int argc, char *argv[]) 6 { 7 int arr[]={ 8 13,14,94,33,82,25,59,94,65,23,45,27,73,25,39 9 }; 10 shellsort(arr,15); 11 int i=0; 12 for(;i<15;i++){ 13 printf("%d ",arr[i]); 14 } 15 return 0; 16 } 17 18 19 /* 20 希尔排序: 21 直接插入排序的改进版,直接插入排序每次只能移动一位,而希尔排序根据特定的步长,移动距离大大增加。 22 希尔排序就是减少增量的排序方法,给出初始设定一个增量,然后根据这个增量将整个序列进行划分,划分成若干个子序列,然后对每 23 个子序列进行直接插入排序。 24 然后再将增量减少,然后再将整个序列划分成若干个子序列,然后在对每个子序列进行直接插入排序,依次类推,直到增量为1时,即 25 对整个序列进行直接插入排序,因为现在的序列已经基本有序,则直接插入排序的效率较高,这样完成后,我们的整个序列就完全有序。 26 */ 27 28 29 void shellsort(int *arr[],int length){ 30 int gap=length/2; //初始设置增量为数组长度的一半,则我们的每个子序列只有两个数据 31 32 for(;gap>=1;gap=gap/2){ //我们每次的排序都是根据步长来确定的,而我们的步长每次排序完成后都要改变,直到步长为1,我们这里采用的步长长度每次为一半 33 //在上面设置了步长以后,则我们的待排序数组已经被分成若干个子序列了,则我们对每个子序列进行直接插入排序 34 35 int m; 36 for(m=0;m<gap;m++){ //我们在这里设置一个循环,这个循环我们用于对每个子序列的起点进行设置,每个子序列的起点都是在0到gap之间的 37 //这样我们就可以把子序列抽离出来,分别是m,m+gap,m+gap+gap...,则我们对这个序列进行直接插入排序 38 int i; 39 int temp; 40 for(i=m+gap;i<length;i=i+gap){ //我们对这个序列进行直接插入排序 41 int j=i; //在这里我们单独定义一个j出来,不能直接对i进行操作,直接操作i以后,i会发生变化,则我们的遍历对象不准确了 42 43 while(j!=m){ 44 if(arr[j]<=arr[j-gap]){ //这个子序列相邻元素之间的距离不再是1,而是gap 45 temp=arr[j-gap]; 46 arr[j-gap]=arr[j]; 47 arr[j]=temp; 48 } 49 j=j-gap; //下标跳转到下一个元素 50 } 51 } 52 53 } 54 55 } 56 }
ok,以上就是希尔排序的基本原理和代码实现。
本文属于博主原创,转载请标明出处。
http://www.cnblogs.com/WuNaiHuaLuo/
时间: 2024-10-03 01:13:14