文字描述

  希尔排序又称缩小增量排序,也属于插入排序类,但在时间效率上较之前的插入排序有较大的改进。

  从之前的直接插入排序的分析得知,时间复杂度为n*n, 有如下两个特点:

  (1)如果待排序记录本身就是“正序”时, 其时间复杂度可减少为n。

  (2)当待排序记录数很小时,直接插入排序的效率也比较高;

  希尔排序正是从这两点分析出发对直接插入排序进行了改进。它的基本思想是:先将整个待排记录序列分割成为若干个子序列分别进行直接插入排序,待整个序列中的记录“基本有序“时,再对全体记录进行一次直接插入排序。

示意图

算法分析

  希尔排序的空间复杂度是所取增量数组的个数加1。

  希尔排序的时间复杂度分析是一个复杂的问题,因为它的时间是所取”增量”序列的函数,这涉及一些数学上尚未解决的难题。但是在大量的前人做的实验基础上推出:当n在某个特定范围内,希尔排序所需的比较和移动次数均约为n^(1.3), 当n无穷大时,可减少到n(log2n)^2。

  增量序列可以有各种取法,但是需注意:应使增量序列中的值没有除1之外的公因子,并且最后一个增量值必须等于1。

  希尔排序是不稳定的

代码实现

 #include <stdio.h>
#include <stdlib.h> #define DEBUG #define EQ(a, b) ((a) == (b))
#define LT(a, b) ((a) < (b))
#define LQ(a, b) ((a) <= (b)) #define MAXSIZE 20
typedef int KeyType;
typedef int InfoType;
typedef struct{
KeyType key;
InfoType otherinfo;
}RedType; typedef struct{
RedType r[MAXSIZE+];
int length;
}SqList; //依次打印顺序表L中的下标和关键字
void PrintList(SqList L){
int i = ;
printf("下标值:");
for(i=; i<=L.length; i++){
printf("[%d] ", i);
}
printf("\n关键字:");
for(i=; i<=L.length; i++){
printf(" %-3d", L.r[i].key);
}
printf("\n其他值:");
for(i=; i<=L.length; i++){
printf(" %-3c", L.r[i].otherinfo);
}
printf("\n\n");
return ;
} /*
*对顺序表L作一趟希尔插入排序。本算法和一趟直接插入
*排序相比,作了以下修改:
* 1。前后记录位置的增量为dk, 而不是1
* 2。r[0]只是暂存单元,不是哨兵
*/
void ShellInsert(SqList *L, int dk)
{
int i = , j = ;
for(i=dk+; i<=L->length; ++i){
//需将L->r[i]插入有序增量子表
if(LT(L->r[i].key, L->r[i-dk].key)){
//暂存在L->r[0]
L->r[] = L->r[i];
for(j=i-dk; j>&&LT(L->r[].key, L->r[j].key); j-=dk){
//记录后移,找插入位置
L->r[j+dk] = L->r[j];
}
//插入位置找到,插入数据
L->r[j+dk] = L->r[];
}
}
} //按照增量序列dlta[0..t-1]对顺序表L作希尔排序
void ShellSort(SqList *L, int dlta[], int t)
{
#ifdef DEBUG
printf("输入数组:\n");
PrintList(*L);
#endif
int k = ;
for(k=; k<t; k++){
//一趟增量为dlta[k]的插入排序
ShellInsert(L, dlta[k]);
#ifdef DEBUG
printf("第%d趟增量%d希尔排序后:\n", k, dlta[k]);
PrintList(*L);
#endif
}
} int main(int argc, char *argv[])
{
if(argc < ){
return -;
}
SqList L;
int i = ;
for(i=; i<argc; i++){
if(i>MAXSIZE)
break;
L.r[i].key = atoi(argv[i]);
L.r[i].otherinfo = 'a'+i-;
}
L.length = (i-);
L.r[].key = ;
L.r[].otherinfo = '';
//希尔排序的增量 依次取9 5 3 1
int dlta[] = {,,,};
//调用希尔排序算法
ShellSort(&L, dlta, );
return ;
}

希尔排序

运行

内部排序->插入排序->希尔排序的更多相关文章

  1. 学习C#之旅 冒泡排序,选择排序,插入排序,希尔排序[资料收集]

    关于冒泡排序,选择排序,插入排序,希尔排序[资料收集]  以下资料来源与网络 冒泡排序:从后到前(或者从前到后)相邻的两个两两进行比较,不满足要求就位置进行交换,一轮下来选择出一个最小(或最大)的放到 ...

  2. 冒泡排序 & 选择排序 & 插入排序 & 希尔排序 JavaScript 实现

    之前用 JavaScript 写过 快速排序 和 归并排序,本文聊聊四个基础排序算法.(本文默认排序结果都是从小到大) 冒泡排序 冒泡排序每次循环结束会将最大的元素 "冒泡" 到最 ...

  3. 数组排序-冒泡排序-选择排序-插入排序-希尔排序-快速排序-Java实现

    这五种排序算法难度依次增加. 冒泡排序: 第一次将数组相邻两个元素依次比较,然后将大的元素往后移,像冒泡一样,最终最大的元素被移到数组的最末尾. 第二次将数组的前n-1个元素取出,然后相邻两个元素依次 ...

  4. 冒泡排序 选择排序 插入排序希尔排序 java

    双向冒泡 package com.huang; public class _014_bubb_sort { int[] b={1,2}; static int a[]={12,4,35,65,43,6 ...

  5. 插入排序、冒泡排序、选择排序、希尔排序、高速排序、归并排序、堆排序和LST基数排序——C++实现

    首先是算法实现文件Sort.h.代码例如以下: <pre name="code" class="java">/* * 实现了八个经常使用的排序算法: ...

  6. 排序算法--希尔排序(Shell Sort)_C#程序实现

    排序算法--希尔排序(Shell Sort)_C#程序实现 排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来非常困难 ...

  7. 《Algorithm算法》笔记:元素排序(2)——希尔排序

    <Algorithm算法>笔记:元素排序(2)——希尔排序 Algorithm算法笔记元素排序2希尔排序 希尔排序思想 为什么是插入排序 h的确定方法 希尔排序的特点 代码 有关排序的介绍 ...

  8. C数据结构排序算法——希尔排序法用法总结(转http://www.cnblogs.com/skywang12345/p/3597597.html)

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

  9. 数据结构和算法(Golang实现)(22)排序算法-希尔排序

    希尔排序 1959 年一个叫Donald L. Shell (March 1, 1924 – November 2, 2015)的美国人在Communications of the ACM 国际计算机 ...

随机推荐

  1. 关于uframe源码的一些解读

    游戏管理. GameManager单例:绑定在不同的gameobject上,还是会每次都实例化一个GameManager但是可以为每一个GameManager赋值一个已经存在的单例---------- ...

  2. 【emWin】例程三十:窗口对象——Multiedit

    简介: 本例程介绍MULTIEDIT的使用方法通过MULTIEDIT 小工具可编辑多行文本.它既 可以被用作简单的文本编辑器,也可以用来显示静态文本.该小工具支持带滚动条 和不带滚动条的滚动 触摸校准 ...

  3. 9patch图的尺寸尽量为偶数

    美工做了一张.9的背景图,宽度110*80 像素,描点如下: 放到720p的智能电视上观看,总感觉怪怪的.仔细观看可以发现,前景图总是不能完全的覆盖掉背景图.总有那么一个像素的点多余出来,如图所示: ...

  4. git push 失败

    先上图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvV29KaWFvRGFaaG9uZw==/font/5a6L5L2T/fontsize/400/fil ...

  5. MySQL 5.7的安装及主从复制(主从同步)

    1.master上开启binlog日志,配置如下 一般mysql配置文件在目录/etc下,叫my.cnf (如果找不到的话也有可能在这些目录下:/etc/my.cnf,/etc/mysql/my.cn ...

  6. mysql 分组查询的结果当成临时表 在求最大值

    select avg(data1) as a from temp WHERE YEAR(mdate)= 2018 and MONTH(mdate)=03 and day(mdate)=25 GROUP ...

  7. [PHP] 02 - Namespace & Class

    两个比较大的话题,独立成本篇. 面向对象编程 一.命名空间 PHP 命名空间可以解决以下两类问题: 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突. 为很长的标识符名称 ...

  8. iOS开发之--解决 swap file “*.swp”already exists!问题

    刚才我在vim导入第三方库的时候,突然发现我把podfile的名字打错了,然后我直接终止了进程,然后你懂得出错了,,E325......., 其实使用vim编辑文件实际上是先copy一份临时文件,病映 ...

  9. 【Vue】转-Vue.js经典开源项目汇总

    版权声明:本文为EnweiTech原创文章,未经博主允许不得转载. https://blog.csdn.net/English0523/article/details/88694219 Vue是什么? ...

  10. elastaicsearch基础----->elastaicsearch的使用(一)

    这里面我们总结一下es的一些基础使用. es的基础用法 一.es索引的创建 在postman中,请求url地址:192.168.1.112:9200/user.请求方式:PUT.请求内容如下: { & ...