内部排序->插入排序->希尔排序
文字描述
希尔排序又称缩小增量排序,也属于插入排序类,但在时间效率上较之前的插入排序有较大的改进。
从之前的直接插入排序的分析得知,时间复杂度为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>&<(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 ;
}
希尔排序
运行

内部排序->插入排序->希尔排序的更多相关文章
- 学习C#之旅 冒泡排序,选择排序,插入排序,希尔排序[资料收集]
关于冒泡排序,选择排序,插入排序,希尔排序[资料收集] 以下资料来源与网络 冒泡排序:从后到前(或者从前到后)相邻的两个两两进行比较,不满足要求就位置进行交换,一轮下来选择出一个最小(或最大)的放到 ...
- 冒泡排序 & 选择排序 & 插入排序 & 希尔排序 JavaScript 实现
之前用 JavaScript 写过 快速排序 和 归并排序,本文聊聊四个基础排序算法.(本文默认排序结果都是从小到大) 冒泡排序 冒泡排序每次循环结束会将最大的元素 "冒泡" 到最 ...
- 数组排序-冒泡排序-选择排序-插入排序-希尔排序-快速排序-Java实现
这五种排序算法难度依次增加. 冒泡排序: 第一次将数组相邻两个元素依次比较,然后将大的元素往后移,像冒泡一样,最终最大的元素被移到数组的最末尾. 第二次将数组的前n-1个元素取出,然后相邻两个元素依次 ...
- 冒泡排序 选择排序 插入排序希尔排序 java
双向冒泡 package com.huang; public class _014_bubb_sort { int[] b={1,2}; static int a[]={12,4,35,65,43,6 ...
- 插入排序、冒泡排序、选择排序、希尔排序、高速排序、归并排序、堆排序和LST基数排序——C++实现
首先是算法实现文件Sort.h.代码例如以下: <pre name="code" class="java">/* * 实现了八个经常使用的排序算法: ...
- 排序算法--希尔排序(Shell Sort)_C#程序实现
排序算法--希尔排序(Shell Sort)_C#程序实现 排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来非常困难 ...
- 《Algorithm算法》笔记:元素排序(2)——希尔排序
<Algorithm算法>笔记:元素排序(2)——希尔排序 Algorithm算法笔记元素排序2希尔排序 希尔排序思想 为什么是插入排序 h的确定方法 希尔排序的特点 代码 有关排序的介绍 ...
- C数据结构排序算法——希尔排序法用法总结(转http://www.cnblogs.com/skywang12345/p/3597597.html)
希尔排序介绍 希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进.该方法又称缩小增量排序,因DL.Shell于1959年提出而得名. 希尔排序实质上是一种分组插入方法.它 ...
- 数据结构和算法(Golang实现)(22)排序算法-希尔排序
希尔排序 1959 年一个叫Donald L. Shell (March 1, 1924 – November 2, 2015)的美国人在Communications of the ACM 国际计算机 ...
随机推荐
- linux每日命令(38):iostat命令
Linux系统中的 iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视.它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况.同 ...
- 【XMPP】Smack源码之消息接收与解析
XmpPullParser 鉴于xmpp协议都是以xml格式来传输,因此源码中解析协议都是用到XmpPullParser来解析xml XmpPullParser很简单,先简单介绍几个比较常用的方法 / ...
- Current online Redo 和 Undo 损坏的处理方法
转自:http://blog.csdn.net/tianlesoftware/article/details/6261475 Oracle 不同故障的恢复方案 http://blog.csdn.net ...
- Oracle分割字符串 REGEXP_SUBSTR用法
分割字符串中所有指定字符,然后成多行参数说明,参数1: 待分割字符串参数2:正则表达式参数3:起始位置,从第几个字符开始正则表达式匹配(默认为1)参数4:标识第几个匹配组,默认为1参数5:模式('i' ...
- 【emWin】例程二十一:窗口对象——Edit
简介: 编辑框通常用作输入文本的主要用户界面,也可使用编辑字段以二进制.十进制或十六进制模式输入值. 触摸校准(上电可选择是否进入校准界面) 实验指导书及代码包下载: 链接:http://pan.ba ...
- kafka性能测试1.0.0
kafka提供工具kafka-producer-perf-test.sh用以压测, 参数 说明 messages 生产者发送总的消息数量 message-size 每条消息大小 batch-size ...
- 【HTTP】 认证和单点登录 【瞎写的…】
■ Cookie,Session,Token HTTP协议是一种无状态的协议.换言之,每一个HTTP请求在得到HTTP回应之后就会断开客户端到服务端的连接.客户端可能会有下一次请求,但是那是下一次的事 ...
- Image Lazy Load:那些延时加载图片的开源插件(jQuery)
图片延时加载技术对大流量的网站来说是十分实用的.目前图片在网站中大量使用,如果不加处理的话会对服务器和带宽造成级大压力,通过只渲染当前用户可见区域的图片,可以极大地减少网站的请求数,降低网络带宽资源. ...
- 服务器最大TCP连接数及调优汇总
启动线程数: 启动线程数=[任务执行时间/(任务执行时间-IO等待时间)]*CPU内核数 最佳启动线程数和CPU内核数量成正比,和IO阻塞时间成反比.如果任务都是CPU计算型任务,那么线程数最多不超过 ...
- Git工作流程最佳实践总结
Git作为一个目前非常流行的版本管理工具,深受开发者的喜爱.那么怎样才能将Git的作用发挥的更好呢?我根据实际的项目经验,归纳总结了以下Git工作流的最佳实践.这里所谓的最佳,是经过多次项目经验后,根 ...