提问者:小点点

Python 3中位数-3快速排序实现,在满足递归深度限制后切换到堆排序


调用的函数:(无论类如何)

def partition( pivot, lst ):
    less, same, more = list(), list(), list()
    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 medianOf3(lst):
"""
From a lst of unordered data, find and return the the median value from
the first, middle and last values.
"""
    finder=[]
    start=lst[0]
    mid=lst[len(lst)//2]
    end=lst[len(lst)-1]
    finder.append(start)
    finder.append(mid)
    finder.append(end)
    finder.sort()
    pivot_val=finder[1]
    return pivot_val

主代码

def quicheSortRec(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 limit==0:
        return heapSort.heapSort(lst)
    else:
        pivot=qsPivotMedian3.medianOf3(lst)        # here we select the first element as the pivot
        less, same, more = qsPivotMedian3.partition(pivot, lst)
        return quicheSortRec(less,limit-1) + same + quicheSortRec(more,limit-1)


def quicheSort(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
"""
    N=len(lst)
    end= int(math.log(N,2))
    if len(lst)==0:
        return list()
    else:
        return quicheSortRec(lst,end)

因此,这段代码应该采用一个列表,并使用中位数为3的快速排序实现对其进行排序,直到达到深度递归限制,此时函数将改为使用堆排序。

但是,当我运行代码时,告诉我长度1和10工作正常,但在那之后,它会给出一个列表索引越界错误

start=lst[0]在3个函数的中位数

我不明白为什么。


共1个答案

匿名用户

没有看到你的测试数据,我们在这里盲目飞行。总的来说,

less, same, more = qsPivotMedian3.partition(pivot, lst)

本身就很好,但您永远不会检查lessmore以查看它们是否为空。即使它们为空,它们也会通过以下方式传递:

    return quicheSortRec(less,limit-1) + same + quicheSortRec(more,limit-1)

quicheSortRec()也不检查它们是否为空:它无条件地调用:

pivot=qsPivotMedian3.medianOf3(lst)  

如果传递了一个空列表,该函数将引发您看到的错误。请注意,您的quicheSort()确实检查了空输入。递归工作函数也应该如此。

BTW,考虑对medianOf3()的重写:

def medianOf3(lst):
    return sorted([lst[0], lst[len(lst)//2], lst[-1]])[1]

这是一个简洁更清晰的情况;-)