在python中的Heapsort

时间:2014-04-09 17:30:03

标签: python sorting heapsort

由于某种原因,我的堆排序运行的速度比它应该的速度慢几个:

def heapsort(unsrt):
   if len(unsrt) == 1:
      return unsrt
   elif len(unsrt) == 2:
      if (unsrt[0] > unsrt[1]):
         unsrt.append(unsrt.pop(0))
      return unsrt
   for i in range((len(unsrt)-2)/2,-1,-1):
      root = i
#      print unsrt
      while True:
         left = root * 2 + 1#left child
         rght = left+1      #right child
         if len(unsrt)-1 < rght: #if you've reached the end
            break
         if len(unsrt) >= rght and unsrt[left] < unsrt[rght]:
            left += 1
            rght += 1
         if unsrt[root] < unsrt[left]:
            unsrt[root], unsrt[left] = unsrt[left], unsrt[root]
            root = left
         else:
            break

   unsrt.append(unsrt.pop(0))
   unsrt[:-1] = heapsort(unsrt[:-1])
   return unsrt

我相信它在n ^ 2(log n)^ 2运行,但我不确定如何减少顺序。有没有办法让我把它变成正确的顺序? unsrt是一个未排序的数组。

1 个答案:

答案 0 :(得分:0)

我认为问题来自这条线:

unsrt.append(unsrt.pop(0))
unsrt[:-1] = heapsort(unsrt[:-1])

基本上,如果我理解你的实现,你会在每次调用时堆积数组,获得最大值,将它放在数组中的最后一个元素上,然后再次进行工作。

我可以在这里找出3个问题:

  1. pop(0) O(n)中运行,因为您称之为 n 次,这是您的 O(n²)
  2. unsrt[:-1]创建了一份列表的副本,该列表也是 O(n),即使由于内存优化而非常快,但仍然是浪费时间
  3. 这个我不是100%肯定,如果我错了,请纠正我。您的heapify算法在 O(nlogn)中运行,并且您正在运行 n 时间,再次 O(n²logn)。您应该将数组堆积一次,这可以在 O(nlogn)中完成(实际上可以在 O(n)中完成)然后删除最小的 n 次。从堆中删除元素可以在O(logn)时间内完成。所以总操作将在 O(nlogn)
  4. 中完成

    所以这就是我要做的事情:

    1. 单独编写heapify函数(使头部最小化)
    2. 单独编写删除min函数
    3. 在sort函数中,只需将数组堆积一次并删除最小 n 次。
    4. 使用此解决方案,您将永远不必翻译数组中的元素。从堆中删除元素时,会自动将其推送到数组中的最后一个未排序位置。