生成随机序列
tt4=tuple([])
小tip:如果想要反复引用
插入排序(一种增量算法)
核心思想:将新值与已排序好的上一个序列进行对比,插到刚好大于他和小于他的值之间,插入抽象为与前一值对比的不停的迭代。相当于打扑克每次抽一张牌插入已经排好序的手牌。
循环不变式:进行迭代时原有某种性质不会改变,可用来做数学归纳法,数学归纳法可用于证明程序的正确性,即起始时条件正确,迭代时条件不变,那么终止时条件仍然正确。
python代码:
tt3=list(tt4)
for i in range(len(tt3)):
j=i-1
while j>=0 and tt3[j]>tt3[j+1]:
bb=tt3[j]
tt3[j]=tt3[j+1]
tt3[j+1]=bb
j-=1
算法复杂度为2*(1+2+……n)=n*(n+1),也就是o(n^2)(这里如果互换可以直接进行就是乘以2,否则是乘以4)
归并排序(一种分治算法)
分治处理的基本思想是分开,解决,再合并
没太看懂上面的意思,写一下我自己的理解吧
我感觉归并算法只有分开和合并,解决在某种程度上就是合并
首先考虑合并的所需的时间复杂度,算法导论中在设计合并函数时比较有意思的是引入了哨兵,目的是在某一组数据见底的时候能反复只对另外一组进行操作(从这个角度来看叫哨兵也挺有道理),因为条件是把小的那一个数放入合并组,所以只要哨兵大于所有数,当一组见底的时候,每次对比都是没见底的那组把数放入合并组中。
此时合并的时间复杂度就是:
n-1(最多对比n-1次)+n(把数放入合并组要执行n次)=2n+1,也就是时间复杂度是o(n)
再考虑总量为m个数据的问题分解成i组(不均分),每组又采用二分归并的方式,此时每组数据分别为n1……ni,那么总的操作次数是2(n1+……ni)-i+i=2m(i为对每组的操作,就是for i in i组,第一层因为差异就是一个常数,是高阶无穷小所以可以忽略),也就是每层的操作次数是一样的,乘以总共的层数log(m),复杂度还是o(mlog(m))
代码:
def hebing(a,b):
...: fd=[]
...: fnu=len(a)+len(b)
...: cc=sum(a)+sum(b)
...: z1=a
...: z1.append(cc)
...: z2=b
...: z2.append(cc)
...: i1=0
...: i2=0
...: for i in range(fnu):
...: if z1[i1]>=z2[i2]:
...: fd.append(z2[i2])
...: i2+=1
...: else:
...: fd.append(z1[i1])
...: i1+=1
...: return fd
def fzs(a):
...: b1=[]
...: b2=[]
...: ft=a
...: ftt=[]
...: while len(ft)>1:
...: for i in map(lambda x:x*2,range(int(len(ft)/2))):
...: if isinstance(ft[i],int):
...: zz1=[ft[i]]
...: zz2=[ft[i+1]]
...: else:
...: zz1=ft[i]
...: zz2=ft[i+1]
...: ftt.append(hebing(zz1,zz2))
...: if int(len(ft)/2)<len(ft)/2:
...: ftt.append(ft[-1])
...: else:
...: pass
...: ft=ftt
...: ftt=[]
...: return ft
问题:为什么分治策略减少了时间复杂度
从每一层操作的量来看,插入排序和分治排序的最大处理个数是一样的,所以分治的优化应该在于减少了循环次数,再进一步看,原因在于有序数组的增量不一样,增量算法的增量是每次循环为1。
分解:把原问题分解成问题相同但规模较小的子问题
解决:解决子问题
合并:将