【发布时间】:2015-02-19 22:48:12
【问题描述】:
我为一项任务创建了这个程序,在该任务中我们需要创建 Quichesort 的实现。这是一种混合排序算法,使用 Quicksort 直到达到一定的递归深度(log2(N),其中 N 是列表的长度),然后切换到 Heapsort,以避免超过最大递归深度。
在测试我的实现时,我发现虽然它的性能通常优于常规快速排序,但堆排序始终优于两者。 谁能解释为什么 Heapsort 表现更好,以及在什么情况下 Quichesort 会比 Quicksort和 Heapsort 更好?
请注意,由于某种原因,该作业将算法称为“Quipsort”。
编辑:显然,“Quichesort”实际上与 Introsort.
我还注意到我的 medianOf3() 函数中的逻辑错误是
导致它为某些输入返回错误的值。这是一个改进的
函数版本:
def medianOf3(lst):
"""
From a lst of unordered data, find and return the the median value from
the first, middle and last values.
"""
first, last = lst[0], lst[-1]
if len(lst) <= 2:
return min(first, last)
middle = lst[(len(lst) - 1) // 2]
return sorted((first, middle, last))[1]
这能解释算法相对较差的性能吗?
Quichesort 代码:
import heapSort # heapSort
import math # log2 (for quicksort depth limit)
def medianOf3(lst):
"""
From a lst of unordered data, find and return the the median value from
the first, middle and last values.
"""
first, last = lst[0], lst[-1]
if len(lst) <= 2:
return min(first, last)
median = lst[len(lst) // 2]
return max(min(first, median), min(median, last))
def partition(pivot, lst):
"""
partition: pivot (element in lst) * List(lst) ->
tuple(List(less), List(same, List(more))).
Where:
List(Less) has values less than the pivot
List(same) has pivot value/s, and
List(more) has values greater than the pivot
e.g. partition(5, [11,4,7,2,5,9,3]) == [4,2,3], [5], [11,7,9]
"""
less, same, more = [], [], []
for val in lst:
if val < pivot:
less.append(val)
elif val > pivot:
more.append(val)
else:
same.append(val)
return less, same, more
def quipSortRec(lst, limit):
"""
A non in-place, depth limited quickSort, using median-of-3 pivot.
Once the limit drops to 0, it uses heapSort instead.
"""
if lst == []:
return []
if limit == 0:
return heapSort.heapSort(lst)
limit -= 1
pivot = medianOf3(lst)
less, same, more = partition(pivot, lst)
return quipSortRec(less, limit) + same + quipSortRec(more, limit)
def quipSort(lst):
"""
The main routine called to do the sort. It should call the
recursive routine with the correct values in order to perform
the sort
"""
depthLim = int(math.log2(len(lst)))
return quipSortRec(lst, depthLim)
堆排序代码:
import heapq # mkHeap (for adding/removing from heap)
def heapSort(lst):
"""
heapSort(List(Orderable)) -> List(Ordered)
performs a heapsort on 'lst' returning a new sorted list
Postcondition: the argument lst is not modified
"""
heap = list(lst)
heapq.heapify(heap)
result = []
while len(heap) > 0:
result.append(heapq.heappop(heap))
return result
【问题讨论】:
-
Quichesort 听起来很好吃。
-
天哪,我的 Python 技能在我 2 年不接触 Python 之后又如潮水般涌现!
-
也许Using heapsort and quicksort together 会有所帮助?至少,你们都有机会去罗切斯特理工学院,因为在谷歌搜索“quipsort”会导致 rit.edu 域中的三个不同 URL。
-
嗯,当你说“有用”时,你是什么意思?通常,您在学校学习的简单算法实际上并没有在现实世界中使用;我们通常偏爱库实现,它们往往会被积极优化。例如Timsort。
标签: python sorting quicksort heapsort