思想:
分解原问题
递归子问题
合并问题解
当问题有子问题时,可以分解,化大为小,各个击破。
那么看下面的图
分解输入
两两合并
算法流程:
归并排序伪代码:
合并伪代码:
python代码:
def merge_sort(nums):
n = len(nums)
if n <= 1:
return nums
mid = n // 2 #分解
left_nums = merge_sort(nums[:mid])
right_nums = merge_sort(nums[mid :])
res = merge(left_nums,right_nums)#合并
return res
def merge(left_nums,right_nums):
#初始化
if not left_nums or not right_nums:
return
n1 = len(left_nums)
n2 = len(right_nums)
res = [0] * (n1 + n2)
# print(aa,nums)
i,j,k = 0,0,0
while i < n1 and j < n2 :
if left_nums[i] <= right_nums[j]:
res[k] = left_nums[i]
i += 1
else:
res[k] = right_nums[j]
j += 1
k += 1
res[k:] = left_nums[i:] if i < n1 else right_nums[j:]
return res
if __name__ == '__main__':
# x = [3,6,8,9,7,8,5,2,3,9,8,41,25,16,25,78,96,34,58]
x = [6,2,3,4]
print(merge_sort(x))
print(x)
或者
class Solution:
def mergeSort(self,nums): #归并排序
if not nums or len(nums) < 2:
return
self.sortProcess(nums,0,len(nums) - 1)
def sortProcess(self,nums,l,r):
if l == r:
return
mid = l + ((r - l) >> 1)
self.sortProcess(nums,l,mid)
self.sortProcess(nums,mid + 1,r)
self.merge(nums,l,mid,r)
def merge(self,nums,l,mid,r):
temp = [0] * (r - l + 1)
i = 0
p1,p2 = l,mid + 1
while p1 <= mid and p2 <= r:
if nums[p1] < nums[p2]:
temp[i] = nums[p1]
p1 += 1
else:
temp[i] = nums[p2]
p2 += 1
i += 1
# temp[i:] = nums[p1:] if p1 <= mid else nums[p2:]
while p1 <= mid:
temp[i] = nums[p1]
i += 1
p1 += 1
while p2 <= r:
temp[i] = nums[p2]
i += 1
p2 += 1
for i in range(len(temp)):
nums[l+i] = temp[i]
用递归树分析时间复杂度:
递归式分析方法:
递归树法
代入法
主定理法
递归树法就是画出像上面的树
代入法就是先猜测最终的复杂度的式子,然后代入。
重点记忆主定理法。
推导:
得到结论:
当f(n)=n^k,时我们可以简化:
几个实例: