1.python实现归并排序算法
参考动图:https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=668244701,2882275964&fm=26&gp=0.jpg
死了好多脑细胞,终于把Merge部分的算法弄清楚了:
①一开始没有考虑到 i,j一个到头一个不到头的情况
②用了一个局部列表brr作为中间变量
# 二、归并排序,升序 # 1.二分 # 思路:1.分,分成0-n/2和n/2 +1 - n。T(n/2) # 2.治 # 3.合,分治法的关键步骤。O(n) # 扫描一遍已经排好序的两部分,两个指针i j,哪个小哪个放在前,然后+1。 # 必须讨论:i,j一个到头一个不到头的情况 # 世间安得两全法,不负如来不负卿? # 暂时木有,只得二者选其一,要么时间,要么空间,我选择负了空间!故用了一个brr列表作为中间变量 # 另外,O(2n)=O(n),所以用并列的循环结构,没必要纠结! arr = [9, 5, 3, 2, 1, -9, 4, 64, 2, -100] def merge(p, r, q): # O(n) brr = [] # print("enter ", p, " ", r, " ", q) i = p j = r + 1 for n in range(p, q + 1): # 从头到尾扫描 if i == r + 1 and j < q + 1: # 必须讨论:i,j一个到头一个不到头的情况 brr += arr[j:q + 1] break elif i < r + 1 and j == q + 1: brr += arr[i:r + 1] break else: if arr[i] > arr[j]: brr.append(arr[j]) j += 1 else: brr.append(arr[i]) i += 1 # print(p, ">>>>>>>>>>", q) # print(brr) arr[p:q + 1] = brr brr.clear() # 清空为[] def merge_sort(p, q): # T(n) = 2T(n/2)+O(n)= O(n*log n)【代公式】 # print(p, "=====", q) if p == q: return r = (p + q) // 2 merge_sort(p, r) # T(n/2) merge_sort(r + 1, q) # T(n/2) merge(p, r, q) # O(n) merge_sort(0, len(arr) - 1) print(arr)
2.时间复杂度分析
merge_sort(p, r) # T(n/2) merge_sort(r + 1, q) # T(n/2) merge(p, r, q) # O(n) def merge_sort(p, q): # T(n) = 2T(n/2)+O(n)= O(n*log n)【代公式,解递归主方法】
3.收获
(1)归并排序是采用分治法(Divide and Conquer)的一个非常典型的应用
(2)分治法包括:分,治,合 三步骤
(3)合,最重要的步骤,这一步的时间复杂度是整个递归的最小单位,因此大多数算法都是在尽量优化Merge的方法;
归并排序中,把两个有序数组Merge成一个有序数组,这一步的复杂度优化成了O(n),因此时间复杂度从O(n^2)变成了O(n log n);
(4)分,将问题分解为规模更小的子问题;
(5)治,将这些规模更小的子问题逐个击破;
作者:西伯尔
出处:http://www.cnblogs.com/sybil-hxl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。