Shell排序(改良的插入排序)
Shell排序算法最初是由D.L Shell于1959年提出,假设要排序的元素有n个,则每个进行插入排序是并不是所偶的元素同时进行,而是去一段间隔。
Shell首先将间隔设定为n/2,然后跳跃的进行插入排序,再来将间隔设定为n/4,跳跃进行排序动作,再来设定时间间隔为n/8、n/16,知道间隔为1之后的最后一次排序终止,由于上一次的排序动作都会将固定间隔内的元素排序好,所以当间隔为1之后的最后一次排序终止,由于上一次的排序动作都会将固定间隔内的元素排序好,所以当间隔越来越小时,某些元素位于正确位置的几率越高,因此最后几次的排序动作将可以大幅减低。
举个例子来说,假如有一未排序的数字如右:89 12 65 97 61 81 27 2 61 98
数字的总数共有10个,所以第一次我们将间隔设定为10/2=5,此时我们对间隔为5的数字进行排序,如下所示:

总结连线的部分表示要一起进行排序的部分,再来将间隔设定为5/2的商,也就是2,则第二次的插入排序对象如下所示:

再来间隔设定为2/2=1,此时就是单纯的插入排序了,由于大部分的元素都已大致排序过了,所以最后一次的插入排序机会没有什么排序动作了:

将间隔设定为n/2是D.L Shell最初所提出,在教科书中使用这个间隔比较好说明,然而Shell排序法的关键在于间隔的设定,例如Sedgewick证明选用以下的间隔可以加快Shell排序算法的速度:

其中4*(2j)2 + 3*(2j) + 1不可超过元素总数n值,使用上式找出j后代入4*(2j)2 + 3*(2j) + 1求得第一个间隔,然后将2j除以2代入求得第二个间隔,再来依次类推。
后来还有人证明有其它的间隔选定方法可以将Shell排序算法的速度再加快;另外Shell排序算法的概念也可以用来改良冒泡排序算法。
C#实例:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
private static void ShellSort(){ int[]new int[] int length int gap WriteNumLine(num); while (gap { for (int k { for (int i { for (int j { if (num[j] { int temp num[j num[j] } else { break; } } } } gap WriteNumLine(num); } WriteNumLine(num);}private static void WriteNumLine(int[]{ foreach (int i in num) { Console.Write(i"); } Console.WriteLine();} |
Shell排序(改良的插入排序)的更多相关文章
- 插入排序与shell排序(希尔排序)
1 .插入排序的过程如同我们平时打扑克牌取牌插入的过程,不断将取出的扑克牌插入已经排好的地方. 插入排序过程初始有序区间大小为1,取出无序区间的首元素,查找有序区间的合适位置,进行插入.不断重复上述过 ...
- 基本排序算法——shell排序java实现
shell排序是对插入排序的一种改进. package basic.sort; import java.util.Arrays; import java.util.Random; public cla ...
- 快排,归并和Shell排序
快速排序 快速排序的执行流程: (1) 先从数列中取出一个数作为基准数. (2) 将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边. (3)再对左右区间重复第二步,直到各区间只有一个数. ...
- 数据结构与算法之--高级排序:shell排序和快速排序
高级排序比简单排序要快的多,简单排序的时间复杂度是O(N^2),希尔(shell)排序大约是O(N*(logN)^2),而快速排序是O(N*logN). 说明:下面以int数组的从小到大排序为例. 希 ...
- 八大排序方法汇总(选择排序,插入排序-简单插入排序、shell排序,交换排序-冒泡排序、快速排序、堆排序,归并排序,计数排序)
2013-08-22 14:55:33 八大排序方法汇总(选择排序-简单选择排序.堆排序,插入排序-简单插入排序.shell排序,交换排序-冒泡排序.快速排序,归并排序,计数排序). 插入排序还可以和 ...
- 七内部排序算法汇总(插入排序、Shell排序、冒泡排序、请选择类别、、高速分拣合并排序、堆排序)
写在前面: 排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素的随意序列,又一次排列成一个按keyword有序的序列.因此排序掌握各种排序算法很重要. 对以下介绍的各个排序,我们假定全部排 ...
- 直接插入排序、折半插入排序、Shell排序、冒泡排序,选择排序
一.直接插入排序 稳定,时间复杂度:最好O(n).最差O(n^2).平均O(n^2).空间复杂度O(1) void InsertSort(int L[], int n) { int i, j,key; ...
- 【排序算法】——冒泡排序、选择排序、插入排序、Shell排序等排序原理及Java实现
排序 1.定义: 所谓排序,即是整理文件中的内容,使其按照关键字递增或递减的顺序进行排列. 输入:n个记录,n1,n2--,其对应1的关键字为k1,k2-- 输出:n(i1),n(i2)--,使得k( ...
- Java常见排序算法之Shell排序
在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...
随机推荐
- 【java集合框架源码剖析系列】java源码剖析之HashMap
前言:之所以打算写java集合框架源码剖析系列博客是因为自己反思了一下阿里内推一面的失败(估计没过,因为写此博客已距阿里巴巴一面一个星期),当时面试完之后感觉自己回答的挺好的,而且据面试官最后说的这几 ...
- Android开发学习之路--传感器之初体验
说到传感器,还是有很多的,有加速度啊,光照啊,磁传感器等等.当然android手机之所以称为智能手机,少不了这几款传感器的功劳了.下面就学习下了,这里主要学习光照,加速度和磁. 新建工程emSenso ...
- 套接字输入流——InputStream
输入缓冲装置里面必须要包含读取字符的通道,否则就谈不上缓冲了,这个通道就是InputStream,它属于jdk中java.io包的类,有了它我们就可以从源头读取字符,它的来源可以有多种多样,这里主要探 ...
- JSP标签JSTL(4)--URL
<c:url>标签作用是将一个URL地址格式化为一个字符串,并且保存在一个变量当中.它具有URL自动重写功能.value指定的URL可以是当前工程的一个URL地址,也可以是其他web工程的 ...
- Android官方命令深入分析之Device Monitor
Android Device Monitor是一个提供了图形化界面的可以对Android应用进行调试和分析的独立的工具.Monitor工具不需要IDE环境,比如Android Studio.包括以下工 ...
- 谈谈Ext JS的组件——容器与布局
概述 在页面中,比较棘手的地方就是布局.而要实现布局,就得有能维护布局的容器.可以说,在我试过和使用过的Javascript框架中,Ext JS的布局是做得最棒的一个,而这得益于它强大的容器类和丰富的 ...
- 认证模式之Spnego模式
Spnego模式是一种由微软提出的使用GSS-API接口的认证模式,它扩展了Kerberos协议,在了解Spnego协议之前必须先了解Kerberos协议,Kerberos协议主要解决身份认证及通信密 ...
- android 4G产品4G网络问题记录
电信.联通.移动切换到LTE_4G都不能通话(提示无法连接到网络)能正常上网,电信EVDO_3G不能通话(提示无法连接到网络)能正常上网这个是正常的,LTE只是针对上网,EVDO也是数据. 目前移动4 ...
- 三层登录实例VB.NET版详解---理论加实战篇
层,百度百科这样解释,首先-重叠起来的东西:重叠起来的东西中的一部分:层次|表层|大气层.其次-重叠:重复:层峦叠嶂|层出不穷.最后-量词,用于可以分出层次的事物,女孩儿强烈的第六感,三层中的层一定是 ...
- hive发杂数据结构的使用,struct,array,map
一个简单介绍http://jimi68.iteye.com/blog/980573 一般的复杂介绍:http://songpo-ath-taobao-com.iteye.com/blog/140513 ...