python 3 median-of-3 Quicksort implementation which switches to heapsort after a recursion depth limit is met

淺唱寂寞╮ 提交于 2019-12-13 05:32:09

问题


Functions called: (regardless of class)

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

main code

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)

so this code is supposed to take a list and sort it using a median of 3 implementation of quicksort, up until it reaches a depth recursion limit, at which point the the function will instead use heapsort.the results of this code are then fed into another program designed to test the algorithm with lists of length 1,10,100,1000,10000,100000.

however, when I run the code, tells me that lengths 1 and 10 work fine, but after that, it gives an list index out of bounds error for

start=lst[0] in the median of 3 function

I cant figure out why.


回答1:


Without seeing your test data, we're flying blind here. In general,

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

is fine on its own, but you never check less or more to see whether they're empty. Even if they are empty, they're passed on via:

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

and quicheSortRec() doesn't check to see whether they're empty either: it unconditionally calls:

pivot=qsPivotMedian3.medianOf3(lst)  

and that function will raise the error you're seeing if it's passed an empty list. Note that your quicheSort() does check for an empty input. The recursive worker function should too.

BTW, consider this rewrite of medianOf3():

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

This is one case where brevity is clearer ;-)



来源:https://stackoverflow.com/questions/20293451/python-3-median-of-3-quicksort-implementation-which-switches-to-heapsort-after-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!