分析合并排序的复杂性

Analysing merge sort complexity

我写的代码如下:

def merge(A, B): #merging two sorted lists
   index_a = index_b = 0
   result = []
   while(index_a < len(A) and index_b < len(B)):
       if(A[index_a] <= B[index_b]):
           result += [A[index_a]]
           index_a += 1
       else:
           result += [B[index_b]]
           index_b += 1
   if(index_a != len(A)):#adds all remaining elements
       result += A[index_a:]
   elif(index_b != len(B)):
       result += B[index_b:]
   return result

def merge_sort(L):
   if(len(L) == 0 or len(L) == 1):
       return L
   else:
       a = merge_sort( L[:len(L)/2] )
       b = merge_sort( L[len(L)/2:] )
       return merge(a , b)

所以我可以理解 merge_sort 函数的复杂性,如上所示,是每个递归调用的 log(n)。我有点困惑的是在合并函数中所采取的步数,首先是两个分配,但之后我不知道如何获得最坏情况下所采取的步数,因为我想不出在哪里停止A或B及后面的加法。

任何帮助将不胜感激。谢谢。

您构建合并的方式虽然性能稍高,但让您更难看出复杂性。试试这个:

def merge(A, B): #merging two sorted lists
   index_a = index_b = 0
   result = []
   while(index_a < len(A) or index_b < len(B)): # NOTE OR
       if index_a < len(A) and (index_b == len(B) or A[index_a] <= B[index_b]): # NOTE EXTRA CONDITIONS
           result += [A[index_a]]
           index_a += 1
       else:
           result += [B[index_b]]
           index_b += 1
   return result

def merge_sort(L):
   ...

这里我用 while 循环条件的更改替换了 "then dump the rest" 代码(允许它 运行 直到两个输入列表都排序),以及 if 的额外条件-声明使它正常工作。如果您假设(正常情况下)连接两个数组的第二个数组的大小为 O(n),则此修改不会改变算法复杂度。 (即使你假设那是常数时间也没有改变,但解释起来稍微复杂一些。)

现在可以看到while循环的执行次数恰好等于列表长度的总和。这样就没有了"worst case".