ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

希尔排序(附有详细C语言代码)

2021-11-10 22:03:56  阅读:206  来源: 互联网

标签:27 C语言 49 55 len gap 希尔 38 排序


希尔排序是基于插入排序的以下两点性质而提出改进方法的:
插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。


其实直接插入排序并不是那么逊的,它在待排序数据基本有序并且数量较少的时候威力还是很大的,甚至比一些高级算法还要高效.对于第二点,我只能说这就是我们shell算法的牛逼的地方了,插入排序每次只能移动数据一位,而shell算法成功的解决了这个问题.


shell算法的核心还是分组,但是这个分组就有门道儿了,因为它会实现取一个小于总数据长度的整数值gap作为分组的步长,什么意思呢?假如我们的待排序数组为:

序号  1      2     3      4      5     6      7      8     9     10

49,38,65,97,76,13,27,49,55,04 

设置gap的值为长度10的一半也就是5,那么第一个和第六个元素就是一组,第二个和第七个元素就是一组,第三个和第八个元素就是一组,第四个和第九个元素就是一组,第五个和第十个元素就是一组,所以一共分为了gap = 5组,

  组     一     二    三     四        五

     序号  1    6   2    7               3    8                4      9                 5    10

     数据  49  13         38  27        65  49        97    55             76   04

  交换后   13  49               27  38             49  65              55     97               04   76

然后如上面每一组之间进行再直接插入排序,比较如果前一个元素比较大,则交换两个元素的位置,直至5组全部交换完毕.此时数组的顺序为

13   27   49   55   04    49   38   65   97   26.

然后gap的值再减半为2,重新分组,也就是第一个 第三个 第五个 第七个 第九个 元素为第一组是13  49  4  38  97, 第二个 第四个 第六个 第八个 第十个元素为一组是27  55  49  65  26.

组                     一                   二

序号 1      3      5      7      9            2      4 6 8   10

数据 13 49   04   38 97       27   55      49 65  26

交换后     04    13   38   49      97          26   27      49     55     65

     

然后如上面对它们两个组分别进行直接插入排序,得到结果为

  4   26   13   27   38    49   49   55   97   65,

之后gap的值再减半为1(要知道gap的值小于1的时候在分组就没意义了,一位你的每一个组至少要有一个元素才能组成一个序列.)这次我们直接对上一次的结果进行一次真正的直接插入排序(为什么说是真正的呢,因为此时步长已经为1)直至得出最终结果:

4   13   26   27   38    49   49   55   65   97.


下面是shell算法的实现代码:

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

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

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

    return 0;
}

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

标签:27,C语言,49,55,len,gap,希尔,38,排序
来源: https://blog.csdn.net/m0_58941767/article/details/121257909

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有