算法思想就是,把数组每次拆成两半,然后递归继续拆,知道数组长度<=1,这样时间复杂度为o(logn),
然后两两合并,比较大小,然后装进临时数组里面,因为两个数组里面的元素只要比较一次,所以时间复杂度为o(n),所以整体的时间复杂度为o(nlogn)。
代码:
class MergeSort():
def __init__(self,s):
self.mergesort(s,0,len(s)-1)
def mergesort(self,s,start,end):
if start < end:
mid = (start + end) // 2
self.mergesort(s, start,mid) #递归
self.mergesort(s, mid+1,end)
self.mergeS(s,start,mid,mid+1,end) #合并
def mergeS(self,s,x1,y1,x2,y2):
i,m,n,j=x1,y1,x2,y2
temp = []
while x1 <= y1 and x2 <=y2: #依次比较大小,小的装进temp里面
if s[x1] < s[x2]:
temp.append(s[x1])
x1+=1
else:
temp.append(s[x2])
x2+=1
while x1<=y1: #假如未取完,就把剩下的元素取出
temp.append(s[x1])
x1 += 1
while x2<=y2:
temp.append(s[x2])
x2 += 1
for num in range(len(temp)): #把temp中元素取出放入s中
s[num+i] = temp[num]
上面的解法存在一个问题每次都要声明一个临时数组,temp设置成全局的,下面可以改成共享一个临时数组。
class MergeSort():
def __init__(self,s):
self.temp = [i for i in s]
self.mergesort(s,0,len(s)-1)
def mergesort(self,s,start,end):
if start < end:
mid = (start + end) // 2
self.mergesort(s, start,mid)
self.mergesort(s, mid+1,end)
self.mergeS(s,start,mid,mid+1,end )
def mergeS(self,s,x1,y1,x2,y2):
m,n = x1,y2
i =x1
while x1 <= y1 and x2 <=y2:
if s[x1] < s[x2]:
self.temp[i] = s[x1]
x1+=1
i+=1
else:
self.temp[i]= s[x2]
x2+=1
i+=1
while x1<=y1:
self.temp[i]= s[x1]
x1 += 1
i+=1
while x2<=y2:
self.temp[i]= s[x2]
x2 += 1
i+=1
for num in range(m,n+1):
s[num] = self.temp[num]
上面的合并函数的写法可以改成下面的样子更加简便。
def mergeS(self,s,x1,y1,x2,y2):
m,n = x1,y2
#只要x1<=y1和x2<=y2有一个满足条件就继续循环
while x1 <= y1 or x2 <=y2:
#若x2已经大于y2,代表第二个数组已经循环完毕,所以把第一个数组全部复制进temp里面,如果不满足判断第二个条件就是s[x1] < s[x2]
if x2>y2 or s[x1] < s[x2]:
self.temp[i] = s[x1]
x1+=1
i+=1
else:
self.temp[i]= s[x2]
x2+=1
i+=1
for num in range(m,n+1):
s[num] = self.temp[num]