一、插入排序的思路
回顾前面提到过的冒泡排序、选择排序,我们发现这两种算法的思路还是比较直观的。然而现在即将隆重推出的插入排序算法则显得有些抽象了。
总体而言,插入排序是把待排序的元素全体看成由两部分组成——已排序完成的部分(有序子串)和尚未排序的部分(无序子串)。
(以从小到大排序为例,假设共计N个元素):
Step1. 在一开始,有序子串只包含一个元素,即第一个元素(python中记为[0])。
Step2.0 从无序子串中取出第一个元素(这里为[1]),与有序子串中的元素作比较。
Step2.1 从有序子串中最后一个元素开始比较,若新取出的元素大于有序子串的当前数,则新取出的元素放在当前位置即可,有序子串的长度+1,无序子串的长度-1
Step2.2 若新取出的元素小于有序子串的当前数,则有序子串长度+1,并且将有序子串当前数后移一位(同时也就是把当前数的原来位置让出来了),取出数继续与有序子串前一位的元素进行比较。
Step2.3 重复2.1和2.2,直到将新取的元素放到合适的位置。若有序子串所有元素均大于新取数,则将其放在有序子串的最前面。完成Step2之后,有序子串扩充一个数,但仍保持有序。
Step3 重复Step2,直到无序子串为空
二、程序实例
用Python实现以上思路非常直观和优雅,下面结合例程中的注释进一步分析插入排序算法
#插入排序 的核心思想:
#把排序过程视作一个不断增长的排好序的子串
#子串最初只有一个元素,即原串的第一个元素。从原串的第二个元素开始,每一个元素都经过比较
#再插入到合适的位置
#by Pospro, 2015-08-29 http://blog.csdn.net/pospro
def insertSort(alist, ord='A'):
if ord=='A': #默认采用升序排列
n=len(alist) #n为元素数量
for i in range(1,n): # i=(1,2,...n-1) 无序子串从[1]开始直到[n-1],同时有序子串也从[0],增加到[n-2]
newElement=alist[i] #无序子串的第一个元素,也即待插入的元素
cnt=i #cnt-1恰好指示有序子串的最后一位,也即有序子串中最大的一个元素
while newElement<alist[cnt-1] and cnt>0: #从后向前比较,直到找到合适的插入位置
alist[cnt]=alist[cnt-1] #如果当前元素比待插入的元素大,则将其后移。空出的位置预备被新元素填入,或者其它元素后移
cnt-=1
alist[cnt]=newElement #循环结束时,cnt恰好指示newElement合适的位置
print alist #取消注释后,可以逐步显示每个过程