算法有很多种分类,我们一种一种来,先来看看插入排序,插入排序的意思是在拿到一个新的数前,之前的序列已经排好,现在的任务就是找到这个新的数字在序列中的位置,这就需要一个个去比较,直到找到一个位置满足要求。插入排序又分为两类。
1、直接插入排序,直接插入排序,名副其实,从序列的第二个数开始,依次与前面已经排列好的数值进行比较,如果发现它比前面的数值都大,则其当前所在位置就是正确位置,否则就要将一系列数值往后迁移一格,直到找到一个数值比它小,那么这个位数值后边那个位置就是当前数值应该在的位置。可以看到直接插入排序在原序列上进行变动,不需要开辟新空间,但是每次加入一个数字时都需要频繁的进行比较和移动,因此这个开销肯定不小,基本上就是n的平方了。
2、shell排序,这种排序起始是变相的直接插入排序,在直接插入排序中,我们是以步长为1进行排序的,如果我们以不同的步长进行排列,而每次依次减小,直到变为1.
现在给出python代码。
#coding:utf-8 #插入排序,每次排序时都假设当前索引处的数字之前所有的数都已经排好#用当前数与前面的数进行比较,找到其所在位置,相应数进行移动。def insertSort(numList): length = len(numList) for i in range(1,length): if numList[i] < numList[i - 1]: temp = numList[i] j = i - 1 while j >= 0: if numList[j] > temp: numList[j + 1] = numList[j] j -= 1 else: numList[j + 1] = temp break if numList[0] > temp:#注意边界条件,可能当前数比原始排好的序列的第一个数的都小 numList[0] = temp #希尔排序,主要是在插入排序的基础上,不是每次以1为步长,而是先从一个比较大的步长开始,间隔进行插入排序,#每排完一个步长,步长相应减小,继续排序,直到步长变为1def shellSort(numList): step = [7,5,3,1] lengthen = len(numList) for i in range(0,lengthen): try: shellInsert(numList,step[i]) except IndexError,e: passdef shellInsert(numList,dk): lengthen = len(numList) for k in range(0,dk): for i in range(k + dk,lengthen,dk): try: if numList[i] < numList[i - dk]: temp = numList[i] j = i - dk while j >= 0: if numList[j] > temp: numList[j + dk] = numList[j] j -= dk else: numList[j + dk] = temp break if numList[k] > temp:#注意这里的边界条件,是要一直到当前序列的第一个数,因此必须是k而不能是0或者其它。 numList[k] = temp except IndexError,e: #主要是有可能会发生越界,为了省去在代码中麻烦的越界判断,直接给个越界报错。 pass def test(): import copy,random a = [] for i in range(100): temp = random.randint(0, 100) while True: for x in range(len(a)): if a[x] == temp: #这里主要是防止了有重复元素出现,也可以免去这一步,直接往数组填随机数,而且这样似乎更合理 temp = random.randint(0, 100) break else: a.append(temp) break # a.append(random.randint(0,100)) for item in a: print item, print ‘\n‘ b = copy.deepcopy(a) insertSort(a) shellSort(b) for x in a: print x, print ‘\n‘ for x in b: print x, if __name__ == ‘__main__‘: test()
时间: 2024-11-04 19:48:43