希尔排序(C语言)-解析

希尔排序

希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因DL.Shell于1959年提出而得名。



  希尔排序(Shell Sort)是将整个待排记录序列

(R1,R2,R3,……,Rn

  按增量 d 划分为 d 个子序列,其中第 i (1 ≤ i ≤ d) 个子序列为

(Ri,Ri+d,Ri+2d,……,Ri+kd

  并分别对各个子序列进行直接插入排序;不断减少增量 d,重复这一过程;直到 d 减少到 1,对整个序列进行一次直接插入排序。增量 d 的取值序列

  称为增量序列。基于增量序列的降序特点,希尔排序也被称为“缩小增量排序”。


  希尔排序与直接插入排序的不同之处在于,直接插入排序每次对相邻记录进行比较,记录最多只移动了一个位置,而希尔排序每次对相隔较远距离

  (即增量)的记录进行比较,使得记录移动时能跨过多个记录,实现宏观上的调整。当增量减小的 1 时,此时序列已基本有序,希尔排序的最后一趟

  就是接近最好情况的直接插入排序。可将前面各趟的“宏观”调整看成是最后一趟的预处理,比如只做一次直接插入排序效率更高。



 假设待排序记录为10个,其对应的关键字序列为

(49  38  65  97  76  13  27  49  55  04)

其中有两个49,后一个49加下划线以示区别。若增量序列为

(5 ,3  ,  1 )

  第一趟的增量 d1 为 5,将 10 个待排记录的分为 5 个子序列,如图所示,分别进行直接插入排序,结果为

(13  27  49  55  04  49  38  65  97  76)。

PS:由于排序后加横线的49排到第一个49前面,因此希尔排序是不稳定的排序方法。

  第二趟的增量 d2 为 3,将上一趟的结果分为 3 个子序列,如图所示,分别进行直接插入排序,结果为

(13  04  49  38  27  49  55  65  97  76)。

(13  04  49  38  27  49  55  65  97  76)。

  第三趟的增量 d3 为 1,对整个序列进行直接插入排序,最后结果为

(04  13  27  38  49  49  55  65  76  97)。



代码(C语言):

 1 #include<stdio.h>
 2 #include<math.h>
 3
 4 #define MAXNUM 10
 5
 6 int main()
 7 {
 8     void shellSort(int array[],int n,int t);//t为排序趟数
 9     int array[MAXNUM],i;
10     printf("input 10 numberd :\n");   //输入
11     for(i = 0;i < 10; i++)            //数组
12         scanf("%d",&array[i]);
13     printf("\n");
14     shellSort(array,MAXNUM,int(log(MAXNUM+1)/log(2)));//排序趟数应为log2(n+1)的整数部分
15     printf("the sorted numbers: \n");
16     for(i = 0;i < 10; i++)            //输出数组
17         printf("%d ",array[i]);
18     printf("\n");
19 }
20
21 //根据当前增量进行插入排序
22 void shellInsert(int array[],int n,int dk)
23 {
24     static int i,j,temp;
25     for(i=dk;i<n;i++)//分别向每组的有序区域插入
26     {
27         temp=array[i];
28         for(j=i-dk;(j>=i%dk)&&array[j]>temp;j-=dk)//比较与记录后移同时进行
29             array[j+dk]=array[j];
30         if(j!=i-dk)
31             array[j+dk]=temp;//插入
32     }
33 }
34
35 //计算Hibbard增量
36 int dkHibbard(int t,int k)
37 {
38     return int(pow(2,t-k+1)-1);
39 }
40
41 //希尔排序
42 void shellSort(int array[],int n,int t)
43 {
44     void shellInsert(int array[],int n,int dk);
45     int i;
46     for(i=1;i<=t;i++)
47         shellInsert(array,n,dkHibbard(t,i));
48 }
49
50 //此写法便于理解,实际应用时应将上述三个函数写成一个函数。

输入/输出:


  希尔排序的时间复杂度是所取增量序列的函数,尚难准确分析。有文献指出,当增量序列为 d[k] = 2t-k+1-1 时,希尔排序的时间复杂度为 O(n1.5),其中 t 为排序趟数, 1 ≤ k ≤ t ≤ [log2(n+1)]。

时间: 2024-08-25 20:33:22

希尔排序(C语言)-解析的相关文章

【算法】希尔排序C语言实现

上一篇文章我们一起学习了直接插入排序,它的原理就是把前i个长度的序列变成有序序列,然后循环迭代,直至整个序列都变为有序的.但是说来说去它还是一个时间复杂度为(n^2)的算法,难道就不能再进一步把时间复杂度降低一阶么?可能有很多同学说快速排序,堆排序,我都会,这些简单的插入排序我都不屑于用.确实,以上几种算法相对于之前的O(n^2)级别的算法真的是弱爆了,效率可能还会差上千万倍,但是我们不妨翻看一下历史,你就会感觉每一种算法的出现都是很可贵的.在1959年D.L.Shell正式提出了我们今天的主角

常见的9种内部排序(C语言实现)

现在已经把常见的9种内部排序算法都用C语言实现了,为了方便自己和大家查看,就弄了这么一个类似于导航目录的东西. 一.冒泡排序 冒泡排序(C语言版) 二.选择排序 选择排序(C语言版) 三.直接插入排序 直接插入排序(C语言版) 四.希尔排序 希尔排序(C语言版) 五.归并排序 归并排序(C语言版) 六.基数排序 基数排序(C语言版) 七.快速排序 快速排序(C语言版) 八.计数排序 计数排序(C语言版) 九.堆排序 堆排序(C语言版) 介绍完这九个常用的排序算法,怎么能没有一个比较呢?下面是我对

希尔排序(Shell&#39;s Sort)的C语言实现

原创文章,转载请注明来自钢铁侠Mac博客http://www.cnblogs.com/gangtiexia 希尔排序(Shell's Sort)又称“缩小增量排序”(Diminishing Increment Sort)的基本思想不断缩小步长后分组排序,具体步骤为 演示实例: C语言实现(编译器Dev-c++5.4.0,源代码后缀.cpp) 1 #include <stdio.h> 2 #define LEN 9 3 4 typedef float keyType; 5 6 typedef s

对c语言系统库函数、堆排序、希尔排序、折半插入排序、快速排序消耗时间的比较

#include <stdio.h> #include <time.h> #define N 100000 /*库比较函数:qsort(int *base,int n,int struct_size,int (*compare)(const void *,const void *))中的比较函数*/ int compare(const void *first, const void *second) { if (*(int *)first > *(int *)second)/

C语言中的排序算法--冒泡排序,选择排序,希尔排序

冒泡排序(Bubble Sort,台湾译为:泡沫排序或气泡排序)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端 维基百科:点击打开链接 [cpp] view plain copy /* 用选择法对10个数进行排序 */ #include<stdio.h> void main() { int i,j,

简单插入排序和希尔排序(原理和C语言实现)

简单插入排序的原理很简单: 所谓插入排序,就是将新加入的数据插入到一个有序数组中,并且保证插入后有序.这就要求要找到插入的位置. (图片来自维基百科) 对于一个已经存在的数组(乱序),要将其有序排列(这里取从小到大),就可以按照下面的步骤: 1.先假定一个有序数组,这个数组只有一个元素,就是第一个元素,它一定是有序的; 2.我们从第二个数(下标为1)开始向后遍历数组; for(insert_index=1; insert_index < arr_len; insert_index++){ } 3

排序(4)---------希尔(shell)排序(C语言实现)

由于考试耽搁了几天,不好意思~~~ 前面的介绍的三种排序算法,都属于简单排序,大家能够看下详细算法,时间复杂度基本都在0(n^2),这样呢,非常多计算机界.数学界的牛人就非常不爽了,他们在家里想啊想,吃饭的时候在想,窝粑粑的时候也在想,到底能不能把时间复杂度搞低点呢.最终,皇天不负有心人啊,王母娘娘显灵了,最终被DL. SHELL这哥们给想出来了.他所创造的希尔(shell)排序是世界上第一个打破0(n^2)的时间复杂度的算法.牛逼不? 好了,言归正传. 希尔排序: 希尔排序,也称递减增量排序算

数据结构之---C语言实现希尔排序

//希尔排序Shell Sort //杨鑫 #include <stdio.h> #include <stdlib.h> void ShellSort(int a[], int length) { int increment; int i,j; int temp; for(increment = length/2; increment > 0; increment /= 2) //用来控制步长,最后递减到1 { // i从第step开始排列,应为插入排序的第一个元素 // 可

一起talk C栗子吧(第二十八回:C语言实例--希尔排序)

各位看官们,大家好,上一回中咱们说的是插入排序的例子,这一回咱们说的例子是:希尔排序.闲话休 提,言归正转.让我们一起talk C栗子吧! 希尔排序是对插入排序的一种改进,希尔排序的原理:先将容器分成若干子容器,然后分别对子容器进行 插入排序,当子容器全部排序完毕后,对全部元素进行一次插入排序. 希尔排序的实现步骤: 1.选取一个增量,增量的大小可以自己定义,其大小在1到容器长度之间: 2.以容器头部到增量位置的元素为起点,从起点到容器尾部依次遍历容器: 3.在步骤2中的遍历过程中,选择一个当前