分治算法
一.归并排序
from IPython.display import Image
Image(filename="./data/10_01.png",width=800,height=960)
递归法
def mergeSortRecursive(myList):
if len(myList)<2:
return
cut=len(myList)//2
listA=myList[:cut]
listB=myList[cut:]
mergeSortRecursive(listA)
mergeSortRecursive(listB)
pointerA=0
pointerB=0
counter=0
while (pointerA<len(listA) and pointerB<len(listB)):
if (listA[pointerA]<listB[pointerB]):
myList[counter]=listA[pointerA]
pointerA+=1
else:
myList[counter]=listB[pointerB]
pointerB+=1
counter+=1
while pointerA<len(listA):
myList[counter]=listA[pointerA]
pointerA+=1
counter+=1
while pointerB<len(listB):
myList[counter]=listB[pointerB]
pointerB+=1
counter+=1
listX=[6,3,-2,0,-1,5,9,7]
mergeSortRecursive(listX)
print(listX)
[-2, -1, 0, 3, 5, 6, 7, 9]
迭代法
Image(filename="./data/10_02.png",width=800,height=960)
def mergeSortIterate(myList):
length=len(myList)
n=1
while n<length:
for i in range(0,length,n*2):
listA=myList[i:i+n]
listB=myList[i+n:i+n*2]
pointerA=0
pointerB=0
counter=i
while (pointerA<len(listA) and pointerB<len(listB)):
if (listA[pointerA]<listB[pointerB]):
myList[counter]=listA[pointerA]
pointerA+=1
else:
myList[counter]=listB[pointerB]
pointerB+=1
counter+=1
while pointerA<len(listA):
myList[counter]=listA[pointerA]
pointerA+=1
counter+=1
while pointerB<len(listB):
myList[counter]=listB[pointerB]
pointerB+=1
counter+=1
n=n*2
myList=[-2,9,0,8,5,-4,8]
mergeSortIterate(myList)
print(myList)
[-4, -2, 0, 5, 8, 8, 9]
二.连续子列表的最大和
Image(filename="./data/10_03.png",width=800,height=960)
Image(filename="./data/10_04.png",width=800,height=960)
def maxSubArray(nums):
if nums==[]:
return
if len(nums)==1:
return nums[0]
cut=len(nums)//2
leftSum=maxSubArray(nums[:cut])
rightSum=maxSubArray(nums[cut:])
leftMiddleSum=0
maxL=0
rightMiddelSum=0
maxR=0
for i in range(cut-1,-1,-1):
leftMiddleSum+=nums[i]
maxL=max(leftMiddleSum,maxL)
for i in range(cut+1,len(nums),1):
rightMiddelSum+=nums[i]
maxR=max(rightMiddelSum,maxR)
return (max(leftSum,maxL+nums[cut]+maxR,rightSum))
maxSum=maxSubArray([-2,1,-3,4,-1,2,1,-5,4])
print(maxSum)
6
三.凸包问题
Image(filename="./data/10_05.png",width=800,height=960)
Image(filename="./data/10_06.png",width=800,height=960)
from math import sqrt
solution=[]
def convexHull(points):
if len(points)<=3:
return points
global solution
points.sort(key=lambda x:x[0])
left_most=points[0]
right_most=points[len(points)-1]
solution.append(left_most)
solution.append(right_most)
helper(points,left_most,right_most,True)
helper(points,left_most,right_most,False)
return solution
def helper(points,left_most,right_most,upBool):
global solution
if len(points)<=1:
return
l=lineHelper(left_most,right_most)
if upBool:
up=[]
max_distance=0
max_point=()
for point in points:
distance=0-(l[0]*point[0]+l[1]*point[1]+l[2])/sqrt(l[0]*l[0]+l[1]*l[1])
if distance>0:
up.append(point)
if distance>max_distance:
max_distance=distance
max_point=point
if max_point!=():
solution.append(max_point)
helper(up,left_most,max_point,True)
helper(up,max_point,right_most,True)
else:
down=[]
min_distance=0
min_point=()
for point in points:
distance=0-(l[0]*point[0]+l[1]*point[1]+l[2])/sqrt(l[0]*l[0]+l[1]*l[1])
if distance<0:
down.append(point)
if distance<min_distance:
min_distance=distance
min_point=point
if min_point!=():
solution.append(min_point)
helper(down,left_most,min_point,False)
helper(down,min_point,right_most,False)
def lineHelper(point1,point2):
if (point1[0]-point2[0])!=0:
m=(point1[1]-point2[1])/(point1[0]-point2[0])
c=point1[1]-m*point1[0]
return [m,-1,c]
else:
return [1,0,point1[0]]
points=[(0,0),(0,4),(-4,0),(5,0),(0,-6),(1,0)]
convexHull(points)
[(-4, 0), (5, 0), (0, 4), (0, -6)]
四.多项式乘法
Image(filename="./data/10_07.png",width=800,height=960)
Image(filename="./data/10_08.png",width=800,height=960)
from cmath import pi
from cmath import exp
import cmath
import numpy as np
def FFT(A,w):
length=len(A)
if length==1:
return [A[0]]
else:
A_even=[]
A_odd=[]
for i in range(0,length//2):
A_even.append(A[2*i])
A_odd.append(A[2*i+1])
F_even=FFT(A_even,w**2)
F_odd=FFT(A_odd,w**2)
x=1
values=[None]*length
for i in range(0,length//2):
values[i]=F_even[i]+x*F_odd[i]
values[i+length//2]=F_even[i]-x*F_odd[i]
x=x*w
return values
def solver(A,B):
length=len(A)+len(B)-1
n=1
while 2**n<length:
n+=1
length=2**n
A.extend([0]*(length-len(A)))
B.extend([0]*(length-len(B)))
w=exp(2*pi*1j/length)
A_values=FFT(A,w)
B_values=FFT(B,w)
C_values=[A_values[i]*B_values[i] for i in range(length)]
result=[int((x/length).real) for x in FFT(C_values,w**(-1))]
while result[-1]==0:
del result[-1]
print(result)
solver([3,2,3,4],[2,0,1])
[5, 3, 9, 10, 3, 4]