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

/*
*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 9

void 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值