数据结构 排序(希尔排序)

//希尔排序法--插入排序升级版
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>

/*
强调:网上,书上的希尔排序法都有问题
希尔排序并非按一个增量d,将一个数组分成若干小的数组,对每个数组进行插入排序,

真正的希尔排序步骤
第一步,通过业界常规 d = 数组长度 / 3 + 1;  求出增量d
第二步:取数组第一个元素,按照增量d的间隔 组成一个新的数组,对这个数组进行增量排序
第三步:再次获取增量d  d = d / 3 + 1; 还是获取数组的第一个元素  按照增量d的间隔 组成一个新的数组,对这个数组进行增量排序
第四步:重复第三步

注意:①每次插入排序的都是第一个元素对应的新数组,没有对第二个元素对应的数组(或者第n个元素对应的数组)进行排序
②希尔排序当d=1的时候  仍然执行了一轮,当d=1 其实就是对整个数组进行一次插入排序

我个人感觉这比插入排序还多了几步
*/

//打印数组
void Print(int * arr, int num){
    if (arr == NULL)
    {
        printf("传入参数不可以为空!
");
        return;
    }
    int i = 0;
    for (int i = 0; i < num; i++)
    {
        printf("%5d", *(arr + i));
    }
    printf("
");
}

//希尔排序
void ShellSort(int *arr, int len){
    //定义每次间隔元素的个数
    int gap = len;
    int i = 0, j = 0, temp = 0, k = 0, m = 0;
    /*
    这里使用do while的原因是希尔排序是当增量d=1时,排序完成(需要以d=1进行排序一次),
    如果使用while,退出条件不好写(gap>1)显然少运行了d=1的情况
    */
    do
    {
        //业界统一实验的间隔将是数组长度的1/3  平均最好情况 经过若干次后,收敛为1
        gap = gap / 3 + 1;
        for (m = 0; m < gap; m++)
        {
            //由第一组数据加上d1  获取第一组数据中的每个元素在后面组中对应位置的数据
            for (i = gap + m; i < len; i += gap)
            {
                k = i;
                temp = arr[k];
                //此时  每间隔d1的元素正好是i循环的数组  对这个新数组中的元素执行插入排序
                //i-gap是子数组的最大下标  现在要插入的元素的下标是i
                for (j = i - gap; j >= 0 && arr[j] >= temp; j -= gap)
                {
                    //插入排序
                    arr[j + gap] = arr[j];
                    k = j;
                }
                arr[k] = temp;
            }
        }
        //打印数组
        printf("
第%d轮
", gap);
        Print(arr, len);
    } while (gap>1);
}

void Test(){
    int i = 0;
    int arr[10] = { 0 };
    //定义时间类型变量
    time_t ts;
    //生成随机数种子
    srand((unsigned int)time(&ts));
    for (i = 0; i < 10; i++)
    {
        arr[i] = (int)(rand() % 100);
    }
    //打印数组
    printf("
原始数据----
");
    Print(arr, 10);
    //希尔排序
    printf("希尔排序之后的数据
");
    //ShellSort(arr,10); 
    ShellSort2(arr, 10);
    Print(arr, 10);
}

void main(){
    Test();
    system("pause");
}

原文地址:https://www.cnblogs.com/zhanggaofeng/p/5747134.html