由一道编程题学会希尔排序

来源:互联网 发布:帝国cms 全站伪静态 编辑:程序博客网 时间:2024/06/05 22:33
/*
*SHELL排序程序。 
该方法的特征是一个元素与它间隔为J 的元素进行比较或交换然后逐步缩小这个间隔到1为止。
J缩小的规律可以是 J<=J/2或J<=(J+1)/2我们取 J<=J/2取整编程。
具体地说方法如下对于N个数据首先让J<=INT(N/2)让X[1]与X[J+1]比较
假设数组名XX[2]与X(J+2)比较...X[N-J]与X[N]比较若次序颠倒则互相交换。
然后再重新比较一轮直到没有交换为止。
于是令J<=INT(J/2)再重复以上操作直到 J=1而且在这一轮比较中没有交换才排序完成。    
题目难以看懂可以跳过!!!

例如 N=9 数据为              5  7  6  4  9  1  3  2  8  交换次数 
J取4=INT(9/2)                  5  1  3  2  8  7  6  4  9    4 
再比较一轮                               不变                       0 
J取2=INT(4/2)                  3  1  5  2  6  4  8  7  9    3 
再比较一轮                               不变                       0 
J取1=INT(2/2)                  1  3  2  5  4  6  7  8  9    4 
再比较一轮                       1  2  3  4  5  6  7  8  9    2 

再比较一轮                             不变停止                  0


读者可以试着分析上下面这个排序的过程, 有助于code!!!

简单来说就是:每隔 N(数字个数除以2取整)个数字比大小,如果前者大于后者,交换顺序,交换次数加 1
a[0] 和 a[4]比  a[1] 和 a[5]比 。。。 a[4] 和 a[8]比, 比到最后一位 ,当交换次数不为 0 继续比较一轮
当交换次数为0 则 每隔 N-1 个数字比大小 同上
       。。。 。。。 。。。
当 N = 1 时候 , 同上,当交换次数为0 ,排序完成
此时 N = 0 (跳出循环条件)


贴上代码:

#include<stdio.h>#define N 9void shell(int a[], int len){    int swapnum = 0;        //记录交换次数    for(int gap = len/2; gap > 0; gap--)    {        while(1)        {            swapnum = 0;            for(int i = gap; i < N; i++)            {                if(a[i-gap] > a[i])                {                    //交换                    int temp = a[i];                    a[i] = a[i-gap];                    a[i-gap] = temp;                    swapnum++;                }            }            printf("交换次数:%d\n", swapnum);            if(swapnum == 0)            {                break;            }        }    }}int main(){    int a[N] = {5,7,6,4,9,1,3,2,8};    int len = sizeof(a)/sizeof(int);    shell(a,len);    for(int i = 0; i < N; i++)    {        printf("%d ", a[i]);    }    return 0;}


原创粉丝点击