首页 > 代码库 > 排序算法系列——插入排序
排序算法系列——插入排序
记录学习点滴,菜鸟成长记
接触算法是研究生期间做项目时,需要编写一些诸如GA、QGA的时候,第一次使用“排序”还是用的Java自带的Comparator接口。后来买了《算法导论》来看,发现果然所有知识都是有专业壁垒的,简单的一个问题尽然蕴藏着如此多的思想,发现此简直欣喜无比,遂决定要好好研究研究。只有深入后才发现,原来算法的不仅仅是按照逻辑顺序写个程序那么简单,好的算法要考虑到方方面面,最简单的时间复杂度就够我学习很长时间了。
将自己学习排序算法的一些理解和感悟记录于此,方便自己温故而知新。
1.排序
我自己对于排序的需求产生于我需要将ArrayList<SomeClass>按照一定的规则进行排序。
排序的抽象定义可以描述为:输入一个序列,输出此序列,使得此序列满足一定的条件。此处的序列可以是List、表、数组等,最重要的是研究算法思想,此处用数组代替讨论。
2.插入排序
《导论》给出的图片很形象,玩过扑克的都有体会。
待排序的数组如同放置在桌上的扑克牌,插入排序就像是左手开始拿牌,右手继而从牌堆顶上拿起一张,从右向左依次比较左手中的牌,直到遇到比其小的牌,然后放置在该扑克牌的右边。
这里面包含两个循环:
(1)右手不停的抓牌是一个循环,直到抓完所有扑克牌,由于扑克牌是确定,我们知道该循环的次数。
(2)右手抓起一张牌后,与左手中的牌比较是另一个循环,循环次数不确定。
其中的判断条件有一个:
(1)右手抓起的牌什么时候比左手中的牌大
3.算法实现
- 按照《导论》使用python实现插入算法:
1 def InsertSort(A): 2 for j in range(2,len(A)+1): 3 key = A[j-1] 4 i = j-1 5 while i > 0 and A[i-1] > key: 6 A[i+1-1] = A[i-1] 7 i = i-1 8 A[i+1-1] = key 9 if __name__ == ‘__main__‘:10 A=[2,1,5,4,6,8,7,9,0,3]11 InsertSort(A)12 print A
- 注释:我为什么要写成A[i+1-1]?这个数组下标问题是我在编写程序时遇到第一个困难,很多时候在考虑下标是否合理、是否越界的问题会打断我的思路,后来我干脆想:数组下标问题只是为了考虑下标所对应的值,既然如此,我在编写程序的时候就都按照符号的实际意义来编写,i就表示实际数组的第i个,在我写完程序后,我在所有的数组取值时-1,这样写可以使得我的思路清晰,可以将思考的重点放在算法思想,而后再去考虑语法问题。
j表示的就是右手抓起的牌,i表示左手上牌,在比较的同时,i递减。
关于此处的理解,大神resume在其博客中关于白话算法系列中的文章,白话经典算法系列之六 快速排序 快速搞定中提到一个“坑”的概念,插入排序也可以这么理解:
A[j]是我们挖出的坑,如果A[j]比左手上的最后一张牌小,那么这个坑就被A[j-1]填上,挖出的A[j]再去比较前面的牌,以此类推。举个不恰当的例子,排队的时候,老师让你按照从低到高排,你迟到了,前面的同学已经排好了,此时就从队伍后面向前走,比你高的都要往后跨一步,直到你遇到第一个比你矮的,你就站在他身后。
4.总结
插入排序是最简单最容易理解的算法,没想到在写博时会有这么多的东西,其实本来还想插入图片更形象的描述,但是我相信大部分的人都比我聪明,就不画蛇添足了。
作为编程菜鸟,看了很多大神写的博客,都是简约而不简单,有很多思想让人受益,以前总是自己理解就完事了,从没有付诸笔端,这次也是鼓足勇气将自己学习的点滴记录下来,帮助自己也希望路过的朋友能不吝指导,共同进步。
5.更新
无。