数据结构_希尔排序(分组加直接插入排序)

希尔排序介绍

希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进。该方法又称缩小增量排序,因DL.Shell于1959年提出而得名。

希尔排序实质上是一种分组插入方法。它的基本思想是:对于n个待排序的数列,取一个小于n的整数gap(gap被称为步长)将待排序元素分成若干个组子序列,所有距离为gap的倍数的记录放在同一个组中;然后,对各组内的元素进行直接插入排序。 这一趟排序完成之后,每一个组的元素都是有序的。然后减小gap的值,并重复执行上述的分组和排序。重复这样的操作,当gap=1时,整个数列就是有序的。 

总结: 5个for循环搞定,当然后面的 for循环if循环停止=完全可以用一个while搞定;

整个流程=分组+直接插入排序=两个for循环分别求出gap和数组起始位置+三个for循环(完全个直接插入排序一模一样的思路,一个for循环找到直接插入的位置,一个for循环后移)

详细见原作者:http://www.cnblogs.com/skywang12345/p/3597597.html

/*
 * 5个for循环搞定
 */
#include"stdio.h"

/*
 * 对希尔排序中的单个组进行排序
 *
 * 参数说明:
 *     a -- 待排序的数组
 *     n -- 数组总的长度
 *     i -- 组的起始位置
 *     gap -- 组的步长
 *
 *  组是"从i开始,将相隔gap长度的数都取出"所组成的!
 */
void group_sort(int a[], int n, int i,int gap)
{
    int j;int p;int k;
    for(j=i+gap;j<n;j+=gap)
    {
        for( p=j-gap;p>=0;p-=gap) //j不变这层循环
        {
            if(a[j]>a[p]) break; //找到插入位置为p+gap
        }
        if(p!=j-gap)  //因为如果等于的话,说明找不到要插入的位置,不用执行下面的交换步骤
        {
            int temp=a[j];  //存起来
            for(k=j-gap;k>p;k-=gap) //右移至p后面一个
            {
                a[k+gap]=a[k];
            }
            a[p+gap]=temp;  //插入正确位置
        }
    }
}
// 先分组再对每组进行直接插入排序

/*
 * 希尔排序
 *
 * 参数说明:
 *     a -- 待排序的数组
 *     n -- 数组的长度
 */
void shell_sort2(int a[], int n)
{
    int i,gap;
    for(gap=n/2;gap>0;gap=gap/2)
    {
        //gap=i; //存储起来
        //group_sort(a,n,1,gap);
        for(i=0;i<gap;i++)  // 每一组进行希尔排序,多少gap就分成多少组
        {
            group_sort(a,n,i,gap); //为什么从i开始弄清楚,i开始进行本组的排序
        }
    }
}
void main(void)
{
    int a[]={5,9,6,3,15,36,14,79,54,14,36,22,99,1,7,100,68,45};
    int length=sizeof(a)/sizeof(a[0]);
    printf("排序前的:");
    for(int i=0;i<length;i++)
        printf("%d ",a[i]);
    printf("
");

    shell_sort2(a,length);

    printf("希尔排序后的");
    for(int j=0;j<length;j++)
        printf("%d ",a[j]);
    printf("
");

}

原文地址:https://www.cnblogs.com/snowwhite/p/4720284.html