2.3-1
[3] [41] [52] [26] [38] [57] [9] [49]
[3|41] [26|52] [38|57] [9|49]
[3|26|41|52] [9|38|49|57]
[3|9|26|38|41|49|52|57]
2.3-2
def meger(A,p,q,r):
'''
:param A:原数组
:param L: 左数组
:param R: 右数组
:return:
'''
d=[] #临时数组
n1=q-p+1
n2=r-q
L=[]
R=[]
for i in range(n1):
L[i]=A[p+i-1]
for j in range(n2):
R[j]=A[q+j]
while L and R:
t1=L[0]
t2=R[0]
if t1<t2:
L.pop(0)
d.append(t1)
else:
R.pop(0)
d.append(t2)
if L :
for i in L :
d.append(i)
else:
for i in R:
d.append(i)
2.3-3
2.3-4
在最坏的情况下把A[n] 插入到已排序的A[1,2,…,n-1] 中需要Θ(n)的时间,因此递归式为(这里面打公式好复杂啊):
# 用递归实现插入排序 这样也算是完成了吧
def inset(a,m):
# 把m插入到已经排好序的a中
key=1
for i in range(len(a)):
if a[i] >m :
a.insert(i,m)
key=0
break
if key:
a.append(m)
def insrt_sort(a,n):
if n-1<0:
return
insrt_sort(a,n-1)
inset(d, a[n-1])
if __name__=='__main__':
a=[9,8,7,6,5,4,3,2,1]
d=[]
k=len(a)
insrt_sort(a,k)
print(d)
2.3-5
二分查找:
def RECURSIVE_BINARY_SEARCH(A, v, low, high):
# 一层层的返回,直到最上面那层
if low > high or low==len(A):
return None
mid = int((low + high) / 2)
# print(mid)
if v == A[mid]:
return mid
elif v > A[mid]:
return RECURSIVE_BINARY_SEARCH(A, v, mid + 1, high)
else :return RECURSIVE_BINARY_SEARCH(A, v, low, mid - 1)
if __name__ == '__main__':
a=[1, 2, 3, 4, 5, 6, 7, 8, 9]
r=len(a)
k=1
res=RECURSIVE_BINARY_SEARCH(a,4,0,9)
print(res)
每次v与中间元素比较时,搜索减少一半,递归式为:
复杂度为Θ(lg(n))
2.3-6
每次运行到while循环的5-7行时,反向扫描已经排好序的A[1..j-1],该循环不仅仅是为了把A[j]放到合适的位置,
同时它把每个大于A[j]的元素向右移动了一次(第六行),在最坏情况下复杂度是Θ(j), 即所有j-1个在A[j]前的
元素都比A[j]大。用二分查找寻找A[j]的位置的时间复杂度为Θ(lg(j)),比移动元素的复杂度要小,因此该循环的
时间复杂度仍旧由移动元素的复杂度Θ(j)决定。
所以,加入二分查找后,插入排序的时间复杂度并不会改善。
2.3-7
1、对S进行排序,时间复杂度最快为Θ(nlg(n))
2、对S中的每一个元素si,i=1,2....n,在S[i+1,..n]中二分查找元素key=x-si,二分查找Θ(lg(n));
如果key存在,返回其与si的下标
否则,继续循环
最多循环n次,复杂度为n*Θ(lgn)
总共的时间复杂度为:Θ(nlg(n)) + n*Θ(lg(n))=Θ(nlg(n))