9.5.1 直接插入排序算法

扑克牌是我们几乎每个人都可能从事过的游戏。而最基本的扑克玩法都是一边摸牌,一边理牌。假如我们拿到了这样一手牌,如图9-5-1。啊,似乎是同花顺呀,别急,我们得理一理顺序才知道是否是真的同花顺。请问,如果是你,应该如何理牌呢?

应该说,哪怕你是第一次玩扑克牌,只要认识这些数字,理牌的方法都是不用教的。将3和4移动到5的左侧,再将2移动到最左侧,顺序就算是理好了。这里,我们的理牌方法,就是直接插入排序法。
        直接插入排序(Straight Insertion Sort)的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表。
        顾名思义,从名称上也可以知道它是一种插入排序的方法。我们来看直接插入排序法的代码。(注:要了解算法的原理,直接看代码和后面的解释并不是最好的办法。将代码输入到电脑中,运行并断点逐行跟踪,参照本文的讲解和图示,观察变量的变化情况,才会收到比较好的效果。这里的代码全是用C语言编写,不过对于擅长C#的读者应该不存在阅读难度。)

void InsertSort(SqList *L)
{ int i,j;for(i=2;i<=L->length;i++){if (L->r[i]<L->r[i-1])   /* 需将L->r[i]插入有序子表 */{L->r[0]=L->r[i];    /* 设置哨兵 */for(j=i-1;L->r[j]>L->r[0];j--)L->r[j+1]=L->r[j];  /* 记录后移 */L->r[j+1]=L->r[0];   /* 插入到正确位置 */}}
}

1) 程序开始运行,此时我们传入的SqList参数的值为length=6,r[6]={0,5,3,4,6,2},其中r[0]=0将用于后面起到哨兵的作用。
2) 第4~13行就是排序的主循环。i从2开始的意思是我们我们假设r[1]=5已经放好位置,后面的牌其实就是插入到它的左侧还是右侧的问题。
3) 第6行,此时i=2,L.r[i]=3比L.r[i-1]=5要小,因此执行第8~11行的操作。第8行,我们将L.r[0]赋值为L.r[i]=3的目的是为了起到第9~10行的循环终止的判断依据。如图9-5-2。图中下方的虚线箭头,就是第10行,L.r[j-1]=L.r[j]的过程,将5右移一位。

4) 此时,第10行就是在移动完成后,空出了空位,然后第11 行L.r[j+1]=L.r[0],将哨兵的3赋值给j=0时的L.r[j+1],也就是说,将扑克牌3放放置到L.r[1]的位置。如图9-5-3。

5) 继续循环,第6行,因为此时i=3,L.r[i]=4比L.r[i-1]=5要小,因此执行第8~11行的操作。将5再右移一位,将4放置到当前5所在位置。如图9-5-4。

6) 再次循环,此时i=4。因为L.r[i]=6比L.r[i-1]=5要大,于是第8~11行代码不执行,此时前三张牌的位置没有变化。如图9-5-5。

7) 再次循环,此时i=5,因为L.r[i]=2比L.r[i-1]=6要小,因此执行第8~11行的操作。由于6、5、4、3都比2小,它们都将右移一位,将2放置到当前3所在位置。如图9-5-6。此时我们的排序也就完成了。

9.5.2 直接插入排序复杂度分析

我们来分析一下这个算法,从空间上来看,它只需要一个记录的辅助空间。因此关键是看它的时间复杂度。
        当最好的情况,也就是要排序的表本身就是有序的,比如纸牌拿到后就是{2,3,4,5,6},那么我们比较次数,其实就是代码第6行每个L.r[i]与L.r[i-1的比较,共比较了 次,由于每次都是L.r[i]>L.r[i-1],因此没有移动的记录,时间复杂度为O(n)。
        当最坏的情况,即待排序表是逆序的情况比如{6,5,4,3,2},此时需要比较 次,而记录的移次数也达到最大值 次。
        如果排序记录是随机的,那么根据概率相同的原则,平均比较和移动次约为n2/4 次。因此,我们得出直接插入排序法的时间复杂度为O(n2)。从这里也看出,同样的O(n2)时间复杂度,直接插入排序法比冒泡和简单选择排序的性能要好一些。

出处:http://www.cnblogs.com/cj723/archive/2011/04/19/2020501.html

《大话数据结构》第9章 排序 9.5 直接插入排序相关推荐

  1. 大话数据结构 第七章 图(二) 最小生成树、最短路径、拓扑排序、关键路径算法

    大话数据结构 第七章 图(二) 最小生成树.最短路径.拓扑排序.关键路径算法 最小生成树 定义 Prim算法 Kruskal算法 最短路径 Dijkstra算法 Floyd算法 拓扑排序 AOV网 拓 ...

  2. 《大话数据结构》样章试读

    <大话数据结构>样章试读 各位童鞋,<大话数据结构>从写作到出版,虽然经历了一些坎坷,但终于还是在今天正式在一些网店发售了.现在提供两章的完整版试读PDF文件,希望能给您有所 ...

  3. 读书笔记-《大话数据结构》第二章算法

    2.3两种算法的比较 #include <iostream> #if 0 //需要运行 100次 int main() {int i,sum=0,n=100;for(i=1;i<=n ...

  4. 【大话数据结构算法】希尔排序

    希尔排序的实质就是分组插入排序,该方法又称为缩小增量排序. 直接插入排序适合于序列基本有序的情况,希尔排序的每趟排序都会使整个序列变得更加有序,等整个序列基本有序了,再来一趟直接插入排序,这样会使排序 ...

  5. 大话数据结构 摘录 第一章 数据结构绪论

    文章目录 启示:数据结构 学习数据机构的重要性 数据结构引发的案例 数据结构的起源 程序设计=数据结构+算法 基础概念与术语 数据 数据元素 数据项 数据对象 数据结构 数据结构:是相互之间存在一种或 ...

  6. 读书笔记-《大话数据结构》第一章数据结构绪论

    1.3数据结构的起源 数据结构:是一门研究非数值计算的程序设计问题中的操作对象,以及它们之间的关系和操作等相关问题的学科. 程序设计=数据结构+算法 1.4基本概念和术语 1.4.1数据:描述客观事物 ...

  7. 大话数据结构第四章栈的应用

    一.斐波契那数列 就是下一项的值等于相邻的上两项元素之和. 这个规律就是斐波契那数列.由此,我知道这个世界是少不了规律的.就算没有规律也要用规律来逼近描述无规律的现象. 迭代和递归的区别:迭代是循环, ...

  8. 大话数据结构第四章栈的基本概念与出栈入栈操作

    一.栈的顺序存储结构 1.基本概念 栈顶就是表尾. 栈顶是栈插入和删除的地方. 栈就是只允许在表尾进行添加或删除,是顺序存储结构线性表的特例或者说简化. 为什么说是简化呢?相对于顺序存储结构来说栈只允 ...

  9. 数据结构与算法系列——排序(3)_折半插入排序

    1. 工作原理(定义) 二分插入排序(Binary Insertion Sort,折半插入排序 OR 拆半插入排序),采用折半查找方法. 二分查找插入排序的原理:是直接插入排序的一个变种:区别是:在有 ...

最新文章

  1. LinkedList源码分析(基于Java8)
  2. 技术人写作和写代码一样重要
  3. [已解决]fdfs-client-py==1.2.6安装失败
  4. 天池 在线编程 求和查找
  5. 红帽产品及技术总裁:未来IT趋势预测
  6. 无论如何都是为了测试傻瓜搜索引擎
  7. chrome控制台如何把vw显示成px_【CSS】679 rem,em,px的区别和使用场景
  8. 华为机试HJ36:字符串加密
  9. 20150401--Dede+搜索页面,评论
  10. 30轧制过程的计算机控制系统,中厚板轧制过程计算机控制系统结构的研制(1)
  11. 计算机存储系统中,有哪些措施可以提高 CPU 访问存储系统的速度?
  12. MySql 5.7.2搭建主从(master/slave)复制
  13. cad汉仪长仿宋体_工程制图国标字体“长仿宋体”下载
  14. PyCharm学习笔记04:PyCharm 键盘映射和快捷键 - Keymap Shortcuts
  15. 和平精英怎么玩?智能找图、鼠标滚轮宏按键玩吃鸡还能匹配手机?
  16. 微信授权登陆跳转提示10003 redirect_uri域名与后台配置不一致
  17. V-REP 添加Vision Sensor与图像获取 | V-REP Adding Vision Sensor and Image Acquisition
  18. EDA技术(VHDL)——0~9999的计数器电路的设计
  19. 基于微信小程序的毕业设计题目(35)PHP医院预约挂号小程序(含开题报告、任务书、中期报告、答辩PPT、论文模板)
  20. 跟着小码哥一起学习OC语法,都在这里了

热门文章

  1. Algorithms_入门基础_如何使用最高效的方式来判断一个数是否是2的N次方
  2. 系统优化怎么做-Linux系统配置优化
  3. MATLAB实现数字识别系统,基于人工神经网络的MATLAB手写数字识别系统
  4. linux c语言乘法口诀,shell 脚本实现乘法口诀表的两种方法——shell与C语言
  5. python集合的并集、交集_Python 集合set()添加删除、交集、并集、集合操作详解
  6. matlab-片状图
  7. 创建docker容器时出现 docker: Error response from daemon, The container name is already in use by container
  8. NodeJs中process.cwd()与__dirname的区别
  9. matlab 邻近度 离群点_Matlab基础学习第一弹!干货来啦!
  10. 初二计算机辅导记录,(初中信息技术兴趣小组活动记录.doc