简体   繁体   English

如何改善python中快速排序数据透视的选择?

[英]How do I improve my quick sort pivot selection in python?

I was originally using only a single random pivot given by 我最初只使用由

pivots = random.randrange(l,r)

Here l and r will be integers that define my range 在这里l和r将是定义我的范围的整数

I wanted to improve the run time by greatly increasing the likely hood that my pivot would be a good pivot by selecting the median of three random pivots. 我希望通过选择三个随机枢轴的中位数来大大增加我的枢轴可能是一个好的枢轴的可能性,从而改善运行时间。 Below is the code I used and it caused my run time to increase by 20%-30%. 下面是我使用的代码,它使我的运行时间增加了20%-30%。

rr = random.randrange
pivots = [ rr(l,r) for i in range(3) ]
pivots.sort()

How do I implement the above to be much faster? 我如何更快地实现上述目的?

Edit: Entire code added below 编辑:在下面添加了整个代码

import random

def quicksort(array, l=0, r=-1):
    # array is list to sort, array is going to be passed by reference, this is new to me, try not to suck
    # l is the left bound of the array to be acte on
    # r is the right bound of the array to act on

    if r == -1:
        r = len(array)

    # base case
    if r-l <= 1:
        return

    # pick the median of 3 possible pivots
    #pivots = [ random.randrange(l,r) for i in range(3) ]
    rr = random.randrange
    pivots = [ rr(l,r) for i in range(3) ]
    pivots.sort()

    i = l+1 # Barrier between below and above piviot, first higher element
    array[l], array[pivots[1]] = array[pivots[1]], array[l]

    for j in range(l+1,r):
        if array[j] < array[l]:
            array[i], array[j] = array[j], array[i]
            i = i+1

    array[l], array[i-1] = array[i-1], array[l]

    quicksort(array, l, i-1)
    quicksort(array, i, r)

    return array

Edit 2: This is the corrected code due. 编辑2:这是正确的代码。 There was an error in the algorithm for picking the 3 pivots 选择3个枢轴的算法中有错误

import random

def quicksort(array, l=0, r=-1):
    # array is list to sort, array is going to be passed by reference, this is new to me, try not to suck
    # l is the left bound of the array to be acte on
    # r is the right bound of the array to act on

    if r == -1:
        r = len(array)

    # base case
    if r-l <= 1:
        return

    # pick the median of 3 possible pivots
    mid = int((l+r)*0.5)
    pivot = 0
    #pivots = [ l, mid, r-1]
    if array[l] > array[mid]:
        if array[r-1]> array[l]:
            pivot = l
        elif array[mid] > array[r-1]:
            pivot = mid
    else:
        if array[r-1] > array[mid]:
            pivot = mid
        else:
            pivot = r-1

    i = l+1 # Barrier between below and above piviot, first higher element
    array[l], array[pivot] = array[pivot], array[l]

    for j in range(l+1,r):
        if array[j] < array[l]:
            array[i], array[j] = array[j], array[i]
            i = i+1

    array[l], array[i-1] = array[i-1], array[l]

    quicksort(array, l, i-1)
    quicksort(array, i, r)

    return array

You could choose the pivot in this way: 您可以通过以下方式选择枢轴:

alen = len(array)
pivots = [[array[0],0], [array[alen//2],alen//2], [array[alen-1],alen-1]]]
pivots.sort(key=lambda tup: tup[0]) #it orders for the first element of the tupla
pivot = pivots[1][1]

Example: 例:

在此处输入图片说明

Though it can be outperformed by random choice on occasion, it's still worth looking into the median-of-medians algorithm for pivot selection (and rank selection in general), which runs in O(n) time. 尽管有时可以通过随机选择来胜过它,但是仍然值得研究中位数中位数算法以进行O(n)时间的数据透视选择(通常是排名选择)。 It's not too far off of what you are currently doing, but there is a stronger assurance behind it that it picks a "good" pivot as opposed to just taking the median of three random numbers. 它与您当前正在做的事情相差不远,但是它背后有一个更有力的保证,那就是它选择了一个“良好”的支点,而不是仅仅取三个随机数的中位数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM