一、插入排序的基本思想

  从初始有序的子集合开始,不断地把新的数据元素插入到已排列有序子集合的合适位置上,使子集合中数据元素的个数不断增多,当子集合等于集合时,插入排序算法结束。常用的 插入排序算法有直接插入排序和希尔排序两种。

  

  二、直接插入排序

  1.直接插入排序的定义

  直接插入排序的基本思想是:顺序地把待排序的数据元素按其值的大小插入到已排序数据元素子集合的适当位置。子集合的数据元素个数从只有一个数据元素开始逐次增大。当子集合大小最终和集合大小相同时排序完毕。

  2.直接插入排序的实现

    public static void straightInsertionSort(int[] L) {
int i, j, temp;
for (i = 0; i < L.length - 1; i++) {
temp = L[i+1]; // 保存要插入的数据元素
j = i;
while (j > -1 && temp <= L[j]) { // 将temp插入到原数组集合中
L[j+1] = L[j];
j--;
}
L[j+1] = temp;
}
}   int[] array1 = {9,1,5,8,3,7,4,6,2};
  初始时,子集合中L0已经排好序,即为{9}
  i=0时,temp=L1=1,j=0,0大于-1且1小于9,则L1=9,j=-1,L0=1,即将1插入到9的前面,集合中{1,9}
  i=1时,temp=L2=5,j=1,1大于-1且5小于9,则L2=9,j=0,0大于-1但5不小于1,则L1=5,集合中{1,5,9}
  i=2时,temp=L3=8,即将8和9比较,8插入到9的前面,8和5比较,不动,8和1比较,也不动,集合中{1,5,8,9}
  ...

  3.直接插入排序的性能分析

  (1)时间复杂度为O(n²)

  • 最好情况是原始数据集合已经全部排好序。这时内层while循环的循环次数每次均为0,外层for循环中每次数据元素的比较次数均为1,数据元素的赋值语句执行次数均为2。因此整个排序过程中比较次数为n-1,移动次数为2(n-1),此时的时间复杂度为O(n)。
  • 最坏情况是与原始数据集合反序排列。这时内层while循环的循环次数每次均为i,这样,整个外层for循环中的比较次数为(1+1)+(2+1)+...+(n-1+1)=(n-1)(n+2)/2,而移动次数为(1+2)+(2+2)+...+(n-1+2)=(n-1)(n+4)/2。此时的时间复杂度为O(n²)。  
  • 随机情况是数据集合中大小的排列是随机的。这时比较次数的期望和移动次数的期望均为n²/4,此时的时间复杂度为O(n²)。

  (2)空间复杂度为O(1)。

  (3)是一种稳定的排序算法。

  三、希尔排序

  1.希尔排序的定义

  希尔排序的基本思想是:把待排序的数据元素分成若干个小组,对同一小组内的数据元素用直接插入法排序;小组的个数逐次缩小;当完成了所有数据元素都在一个组内的排序后排序过程结束。希尔排序又称作缩小增量排序。

  在直接插入排序算法的性能分析中可以得出结论:原始数据集合越接近有序,直接插入排序算法的时间效率越高,其时间效率在O(n)~O(n²)之间。这个结论是希尔排序算法能够成立的基础。希尔排序算法把待排序数据元素分成若干小组,在小组内用直接插入排序算法排序,当把若干个小组合并为一个小组时,组中的数据元素集合将会接近有序,这样各组内的直接插入排序算法的时间效率就很好,最终整个希尔排序的时间效率就很高。

  2.希尔排序的实现

    public static void shellSort(int[] L, int[] d) {
int i, j, k, m, span;
int temp;
for (m= 0; m < d.length; m++) {
span = d[m];
for (k = 0; k < span; k++) {
/********将i=0换成i=k,1换成span的直接插入排序**********/
for (i = k; i < L.length - span; i = i + span) {
temp = L[i+span];
j = i;
while (j > -1 && temp <= L[j]) {
L[j + span] = L[j];
j = j - span;
}
L[j + span] = temp;
print(L);
}
/***********************************************/
}
System.out.print("span的值为" + span + "时得到的序列为: ");
print(L);
}
}

  分析代码执行过程与输出为:

int[] array1 = {9,1,5,8,3,7,4,6,2};int[] d = {4,2,1};
分析执行过程:
m=0时,span=4,k=0时,i=0,j=0时,交换9和3得到{3,1,5,8,9,7,4,6,2};i=4,j=4时,交换9和2得到{3,1,5,8,2,7,4,6,9};j=0时,交换3和2得到{2,1,5,8,3,7,4,6,9};排序{2,3,9}
m=0时,span=4,k=1时,i=1,1和7不交换,排序{1,7}
m=0时,span=4,k=2时,i=2,交换5和4,得到{2,1,4,8,3,7,5,6,9};排序{4,5}
m=0时,span=4,k=3时,i=3,交换8和6,得到{2,1,4,6,3,7,5,8,9};排序{6,8}
m=0结束,得到{2,1,4,6,3,7,5,8,9};可以发现数字1、2等小数字已经在前两位,而8、9等大数字已经在后两位,整个序列已经基本有序了。
m=1时,span=2,k=0时,排序{2,4,3,5,9}为{2,3,4,5,9}
m=1时,span=2,k=1时,排序{1,6,7,8}
m=1结束,交叉两个排序得到{2,1,3,6,4,7,5,8,9}即将之前5个和4个分别直接插入排序,然后插入到原来的位置
m=2时,span=1,k=0时,排序{2,1,3,6,4,7,5,8,9}得到{1,2,3,4,5,6,7,8,9}
输出为:
希尔排序前: 9 1 5 8 3 7 4 6 2
span的值为4时得到的序列为: 2 1 4 6 3 7 5 8 9
span的值为2时得到的序列为: 2 1 3 6 4 7 5 8 9
span的值为1时得到的序列为: 1 2 3 4 5 6 7 8 9
希尔排序后: 1 2 3 4 5 6 7 8 9

  3.希尔排序的性能分析

  (1)时间复杂度

  希尔排序增量序列的选取非常关键,需要注意的是增量序列的最后一个增量值必须是1才行。通过设置合适的增量序列,可以使得时间复杂度为O(n3/2),要好于直接插入排序的O(n²)。

  (2)空间复杂度

  希尔排序算法的空间复杂度为O(1)。

  (3)稳定性

  由于希尔排序算法是按增量分组进行的排序,两个相同的数据元素有可能分在不同的组中,所以希尔排序算法是一种不稳定的排序算法。

  

数据结构(四十六)插入排序(1.直接插入排序(O(n²)) 2.希尔排序(O(n3/2)))的更多相关文章

  1. NeHe OpenGL教程 第四十六课:全屏反走样

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  2. 四十六、android中的Bitmap

    四十六.android中的Bitmap: http://www.cnblogs.com/linjiqin/archive/2011/12/28/2304940.html 四十七.实现调用Android ...

  3. Android简易实战教程--第四十六话《RecyclerView竖向和横向滚动》

    Android5.X后,引入了RecyclerView,这个控件使用起来非常的方便,不但可以完成listView的效果,而且还可以实现ListView无法实现的效果.当然,在新能方便也做了大大的提高. ...

  4. “全栈2019”Java第四十六章:继承与字段

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  5. 第四十六个知识点 在Sigma协议中,正确性,公正性和零知识性意味着什么

    第四十六个知识点 在Sigma协议中,正确性,公正性和零知识性意味着什么 Sigma协议 Sigma协议是Alice想要向Bob证明一些东西的协议(Alice知道一些秘密).他们有下面的一般范式:Al ...

  6. abp(net core)+easyui+efcore实现仓储管理系统——入库管理之十(四十六)

    abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ...

  7. Deep learning:四十六(DropConnect简单理解)

    和maxout(maxout简单理解)一样,DropConnect也是在ICML2013上发表的,同样也是为了提高Deep Network的泛化能力的,两者都号称是对Dropout(Dropout简单 ...

  8. Python之路(第四十六篇)多种方法实现python线程池(threadpool模块\multiprocessing.dummy模块\concurrent.futures模块)

    一.线程池 很久(python2.6)之前python没有官方的线程池模块,只有第三方的threadpool模块, 之后再python2.6加入了multiprocessing.dummy 作为可以使 ...

  9. (四十六)c#Winform自定义控件-水波进度条-HZHControls

    官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...

随机推荐

  1. 判断java中最多的词组

    其中的难点,是空格,以及如果第一个是空格怎么办,虽然事后看着很简单,但是做的时候却十分的困难! static void Daunyu()throws IOException {     Word wo ...

  2. 重学JavaScript之面向对象的程序设计(继承)

    1. 继承 ES 中只支持实现继承,而且其实现继承主要依靠原型链来实现的. 2. 原型链 ES中 描述了 原型链的概念,并将原型链作为实现继承的主要方法.其基本思想是利用原型让一个引用类型继承另一个引 ...

  3. springmvc(二)

    请求信息转换 异步发送表单数据到JavaBean,并响应JSON文本返回 操作步骤:(1)加入Jackson2或fastjson框架包,springmvc默认支持Jackon2,不需要做任何操作,而f ...

  4. python自动化测试三部曲之untitest框架

    终于等到十一,有时间写博客了,准备利用十一这几天的假期把这个系列的博客写完 该系列文章本人准备写三篇博客 第一篇:介绍python自动化测试框架unittest 第二篇:介绍django框架+requ ...

  5. mysql 排序规则

    一.对比 1.utf8_general_ci 不区分大小写,utf8_general_cs 区分大小写 2.utf8_bin: compare strings by the binary value ...

  6. JQuery .width()/.css("width")方法 比较

    1. 获取到的值的区别 获取到的为实际宽度,不包括 内边距 和 边框: <div id="aa"> ...... </div> // 1. width() ...

  7. Nebula Graph 技术总监陈恒:图数据库怎么和深度学习框架进行结合?

    引子 Nebula Graph 的技术总监在 09.24 - 09.30 期间同开源中国·高手问答的小伙伴们以「图数据库的设计和实践」为切入点展开讨论,包括:「图数据库的存储设计」.「图数据库的计算设 ...

  8. 快学Scala 第二十课 (trait的构造顺序)

    trait的构造顺序: 首先调用超类构造器 特质构造器在超类构造器之后,类构造器之前执行 特质从左向右被构造 每个特质当中,父特质先被构造 如果多个特质共有一个父特质,而那个父特质已经被构造,则不会被 ...

  9. Spring项目启动报"Could not resolve placeholder"解决

    1.问题的起因: 除去properites文件路径错误.拼写错误外,出现"Could not resolve placeholder"很有可能是使用了多个PropertyPlace ...

  10. java中的String是不可变类

    String s = "hello "; s += "world"; 这两行代码执行后,原始的String对象中的内容没有变 在这段代码中,s原先指向一个Str ...