【问题标题】:Why is my mergesort implementation slower than bubble sort and insertion sort?为什么我的归并排序实现比冒泡排序和插入排序慢?
【发布时间】:2014-12-04 03:11:51
【问题描述】:

我试图比较不同排序算法的时间复杂度(时间执行)。我在比较冒泡排序、插入排序、快速排序和融合排序(mergesort)。

我知道归并排序和快速排序比其他排序更快,但是当我尝试比较这些方法的执行时间时,归并排序总是比其他所有方法花费更多的时间。我尝试使用 1,000 到 10,000 个元素的列表。谁能告诉我为什么?

这是我的归并排序代码:

def inserer(element, ls):
   if  ls==[]:
       return [element]
   elif element<= ls[0]:
       return [element] + ls
   else:
       return [ls[0]] + inserer(element, ls[1:len(ls)])

def fusion(L1,L2):
   if L1==[]:
       return L2
   elif L2==[]:
       return L1
   else:
       return fusion(L1[1:len(L1)],inserer(L1[0], L2))


def triFusion (ls):
   n=len(ls)
   if n==0 or n==1:
       return ls
   else:
       return fusion(triFusion(ls[0:n//2]),triFusion(ls[n//2:n]))

【问题讨论】:

    标签: sorting time-complexity mergesort


    【解决方案1】:

    我认为这里的问题是您的合并(融合)功能的实现方式使其比需要的慢得多。这是你的代码:

    def fusion(L1,L2):
       if L1==[]:
           return L2
       elif L2==[]:
           return L1
       else:
           return fusion(L1[1:len(L1)],inserer(L1[0], L2))
    

    您的代码是通过重复获取L1 的第一个元素,通过线性搜索将其插入L2 来实现的,然后重复。这种方法的时间复杂度在最坏的情况下是 O(n2),因为第一次插入可能必须扫描 n 个元素才能找到元素的正确位置,第二次可能必须扫描超过 n + 1,第三个 n + 2,等等。

    这打破了您通常使用合并排序获得的良好时间限制。通常,合并操作的实现时间为 O(n)。由于mergesort对原来一半大小的数组进行两次递归调用,然后调用merge,因此mergesort的正常时间复杂度遵循这种递归:

    T(n) = 2T(n / 2) + O(n)

    使用主定理求解到 O(n log n)。但是,在您的情况下,由于您的合并步骤需要时间 O(n2),因此运行时是

    T(n) = 2T(n / 2) + O(n2)

    主定理所说的求解为 O(n2)。换句话说,您的实现的时间复杂度是二次的,就像冒泡排序和插入排序一样,但由于它对低效算法进行大量调用,因此可能具有更高的常数因子。

    要解决此问题,请尝试重写合并算法以在线性时间内运行。这可能会使您的代码运行得更快、更快。

    【讨论】:

      猜你喜欢
      • 2017-03-18
      • 2014-12-11
      • 2011-11-30
      • 1970-01-01
      • 1970-01-01
      • 2012-05-12
      • 2021-05-13
      • 2015-04-25
      • 2015-09-12
      相关资源
      最近更新 更多