希尔排序(C语言实现)

算法思想
  希尔排序是特殊的插入排序,直接插入排序每次插入前的遍历步长为1,而希尔排序是将待排序列分为若干个子序列,对这些子序列分别进行直接插入排序,当每个子序列长度为1时,再进行一次直接插入排序时,结果一定是有序的。常见的划分子序列的方法有:初始步长(两个子序列相应元素相差的距离)为要排的数的一半,之后每执行一次步长折半。
希尔排序的过程演示如下:
希尔排序

代码实现

#include <stdio.h>
#include <malloc.h>

void Shell_sort(int *a, int len);   //函数声明

int main(void)
{
    int i;
    int len;
    int * a;
    printf("请输入要排的数的个数:");
    scanf("%d",&len);
    a = (int *)malloc(len * sizeof(int)); // 动态定义数组
    printf("请输入要排的数:\n");
    for (i = 0; i < len; i++) {    //数组值的输入
        scanf("%d",&a[i]);
    }   
    Shell_sort(a, len);    //调用希尔排序函数
    printf("希尔升序排列后结果为:\n");
    for (i = 0; i < len; i++) {   //排序后的结果的输出
        printf("%d\t",a[i]);
    }
    printf("\n");

    return 0;
}
void Shell_sort(int *a, int len)
{
    int i;
    int j;
    int temp;  
    int gap;  //步长
    for (gap = len / 2; gap >= 1; gap /= 2) {  // 步长初始化为数组长度的一半,每次遍历后步长减半
        for (i = 0 + gap; i < len; i += gap) {   //对步长为gap的元素进行直插排序,当gap为1时,就是直插排序
            temp = a[i];  //备份a[i]的值
            j = i - gap;  //j初始化为i的前一个元素(与i相差gap长度)
            while (j >= 0 && a[j] > temp) {
                a[j + gap] = a[j];  //将在a[i]前且比temp的值大的元素向后移动一位
                j -= gap;
            }
            a[j + gap] = temp; 
        }
    }
}

时间复杂度
  希尔排序的时间复杂度依赖于增量序列的函数,有人在大量的实验后得出的结论:当n在某个特定的范围后,在最优的情况下,希尔排序的时间复杂度为O(n^1.3),在最差的情况下,希尔排序的时间复杂度为:O(n^2).
空间复杂度
  希尔排序的空间复杂度:O(1).

图片来源:希尔排序演示图片

猜你喜欢

转载自blog.csdn.net/qq_38253837/article/details/79118631