一、希尔排序的介绍

  希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的记录越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。  

二、希尔排序的原理

  在前面文章中介绍的直接插入排序,它对于已经基本有序的数据进行排序,效率会很高,而如果对于最初的数据是倒序排列的,则每次比较都需要移动数据,导致算法效率降低。

希尔排序的基本思想就是:将需要排序的序列逻辑上划分为若干个较小的序列(但并非真的分割成若干分区),对这些逻辑上序列进行直接插入排序,通过这样的操作可使需要排序的数列基本有序,最后再使用一次直接插入排序。

在希尔排序中首先要解决的是怎样划分序列,对于子序列的构成不是简单地分段,而是采取将相隔某个增量的数据组成一个序列。一般选择增量的规则是:取上一个增量的一半作为此次子序列划分的增量,一般初始值元素的总数量的一半。

三、希尔排序的图解 

四、希尔排序的python代码实现

# 创建一个希尔排序的函数
def shell_sort(alist):
# 需要排序数组的个数
N = len(alist)
# 最初选取的步长
gap = N//2 # 根据每次不同的步长,对分组内的数据进行排序
# 如果步长没有减为1就继续执行
while gap>0:
# 对每个分组进行插入排序,
# 因为插入排序从第二个元素开始,而这里第二个元素的下标就是gap
# 所以i的起始点是gap
for i in range(gap,N):
# 控制每个分组内相邻的两个元素,逻辑上相邻的两个元素间距为gap,
# j的前一个元素比它少一个gap距离,所以for循环中j的步长为 -gap
for j in range(i,0,-gap):
# 判断和逻辑上的分组相邻的两个数据大小
if alist[j]<alist[j-gap] and j-gap>=0:
# 交换
temp = alist[j]
alist[j] = alist[j-gap]
alist[j-gap] = temp
# 改变步长
gap = gap//2 numlist = [5,7,8,3,1,2,4,6,9]
print("排序前:%s"%numlist)
shell_sort(numlist)
print("排序后:%s"%numlist)

运行结果为:

排序前:[5, 7, 8, 3, 1, 2, 4, 6, 9]
排序后:[1, 2, 3, 4, 5, 6, 7, 8, 9]

五、希尔排序的C语言实现

#include <stdio.h>
// 创建一个希尔排序的函数
void shell_sort(int arr[],int arrLength,int gap)
{
// 根据每次不同的步长,对分组内的数据进行排序
// 如果步长没有减为1就继续执行
while (gap>)
{
// 对每个分组进行插入排序,
// 因为插入排序从第二个元素开始,而这里第二个元素的下标就是gap,
// 所以i的起始点是gap
for (int i = gap; i<arrLength; i++)
{
// 控制每个分组内相邻的两个元素,逻辑上相邻的两个元素间距为gap,
// j的前一个元素比它少一个gap距离,所以for循环中j每次减少一个gap
// 因为j-gap是上一个元素的下标,也必须保证大于等于0
for (int j = i; j>&&j-gap>=; j=j-gap)
{
// 判断和逻辑上的分组相邻的两个数据大小
if (arr[j]<arr[j-gap])
{
// 交换
int temp = arr[j];
arr[j] = arr[j-gap];
arr[j-gap] = temp;
}
}
}
gap = gap/;
}
} int main(int argc, const char * argv[]) { // 定义数组
int array[] = {,,,,,,,,};
// 希尔排序的声明
void shell_sort(int arr[],int arrLength,int gap);
// 计算数组长度
int len = sizeof(array)/sizeof(int);
// 制定gap为二分之一的长度
int g = len/;
// 使用希尔排序
shell_sort(array, len, g);
// 验证
for (int i = ; i<len; i++)
{
printf("%d ",array[i]);
} return ;
}

运行结果为:

        

六、希尔排序的时间复杂度

  • 最优时间复杂度:根据步长序列的不同而不同
  • 最坏时间复杂度:O(n2)

七、希尔排序的稳定性

  由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。

python算法与数据结构-希尔排序算法(35)的更多相关文章

  1. python算法与数据结构-选择排序算法(33)

    一.选择排序的介绍 选择排序(Selection sort)是一种简单直观的排序算法.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素, ...

  2. 插入排序算法--直接插入算法,折半排序算法,希尔排序算法(C#实现)

    插入排序算法主要分为:直接插入算法,折半排序算法(二分插入算法),希尔排序算法,后两种是直接插入算法的改良.因此直接插入算法是基础,这里先进行直接插入算法的分析与编码. 直接插入算法的排序思想:假设有 ...

  3. python算法介绍:希尔排序

    python作为一种新的语言,在很多功能自然要比Java要好一些,也容易让人接受,而且不管您是成年人还是少儿都可以学习这个语言,今天就为大家来分享一个python算法教程之希尔排序,现在我们就来看看吧 ...

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

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

  5. Python 一网打尽<排序算法>之从希尔排序算法的分治哲学开始

    1. 前言 本文将介绍希尔排序.归并排序.基数排序(桶排序).堆排序. 在所有的排序算法中,冒泡.插入.选择属于相类似的排序算法,这类算法的共同点:通过不停地比较,再使用交换逻辑重新确定数据的位置. ...

  6. 基于python的七种经典排序算法

    参考书目:<大话数据结构> 一.排序的基本概念和分类 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法. ...

  7. Python实现十大经典排序算法(史上最简单)。

    十大排序算法(Python实现)一. 算法介绍及相关概念解读 算法分类十种常见排序算法可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn), ...

  8. Python实现十大经典排序算法(史上最简单)

    十大排序算法(Python实现)一. 算法介绍及相关概念解读 算法分类十种常见排序算法可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn), ...

  9. 基于python的七种经典排序算法(转)

    一.排序的基本概念和分类 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法. 排序的稳定性:经过某种排序后,如果两个 ...

随机推荐

  1. 使用 Node.js 写一个代码生成器

    背景 第一次接触代码生成器用的是动软代码生成器,数据库设计好之后,一键生成后端 curd代码.之后也用过 CodeSmith , T4.目前市面上也有很多优秀的代码生成器,而且大部分都提供可视化界面操 ...

  2. Oracle通过命令导入数据存储文件

    imp ztdev/ztdev FROMUSER=zt_base TOUSER=ztdev file=/home/oracle/zt_base_1023_sc_kk_new.dmp log=zt_ba ...

  3. 利用VBA来实现,输入日文之后,输出它的假名即读法

    背景:当你输日文汉字的额时候,输出它的读音. 如下图所示 实现的代码如下 Option Explicit ' Replace を まとめて おこなう Private Function ReplaceA ...

  4. 七、spring生命周期之初始化和销毁方法

    一.通过@Bean指定初始化和销毁方法 在以往的xml中,我们是这样配置的 <bean id="exampleInitBean" class="examples.E ...

  5. 使用Xshell采用证书登录Linux

    1,工具--- 用户key生成向导,选择秘钥类型,注意DSA只能选择1024位级以下,超过1024位的服务器不认. 2 给公钥取一个名字,并设置密码,保存为文件 3 在linux 用户目录,用cd  ...

  6. 安装donkeyid

    cd /usr/local/php/include/php/ext sudo git clone https://github.com/osgochina/donkeyid.git cd /usr/l ...

  7. python函数知识五 推导式和内置函数一(了解)

    17.推导式: 推导式:将for循环多行变成一行 list推导式:[] #普通模式 print([i for i in range(20)]) #循环模式 #[变量 for i in range(20 ...

  8. SpirngBoot--错误消息的定制

    在SpringBoot中发生了4xx 5xx之类的错误,SpringBoot默认会发一个/error的请求,该请求由BasicErrorController处理,即在SpringBoot中错误处理也是 ...

  9. C# vb .net实现色调调整特效滤镜

    在.net中,如何简单快捷地实现Photoshop滤镜组中的色调调整呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第一步 ...

  10. 【转载】 C#使用string.IsNullOrWhiteSpace方法判断字符串是否为非空字符

    在C#编程过程中,很多时候需要判断传入过来的字符串是否为Null或者空字符或者空白字符,此时就可以使用到string.IsNullOrWhiteSpace方法来判断,如果字符串为null或者空字符Em ...