在Python中使用就地快速选择(又称线性时间选择)的错误

时间:2016-06-17 14:26:54

标签: python algorithm quicksort

我正在学习斯坦福课程"算法:设计和分析,第1部分",同时尝试在Python中实现一个就地随机选择算法(即基于快速排序的选择),我相信我的分区功能是正确的,但我无法弄清楚选择部分为什么会失败,任何建议都非常感谢。我的代码如下:

import random
def random_selection(nums, start, end, i):   
    if end == start:
        return nums[start]
    elif start < end:       
        pivot = partition(nums, start, end)        
        if pivot == i:            
            return nums[pivot]
        elif pivot < i:
            # original code suffering from logic error with indices, fixed by changing 'i - pivot' into 'i' 
            # return random_selection(nums, pivot + 1, end, i - pivot)
            return random_selection(nums, pivot + 1, end, i)
        elif pivot > i:
            return random_selection(nums, start, pivot - 1, i)
    else:       
        return False        


def partition(nums, start, end):
    pivot_value = nums[start]
    left = start + 1
    right = end
    done = False
    while not done:
        while left <= right and nums[left] < pivot_value:
            left += 1

        while left <= right and nums[right] > pivot_value:
            right -= 1

        if left > right:
            done = True
        else:
            nums[left], nums[right] = nums[right], nums[left]
    nums[start], nums[right] = nums[right], nums[start]
    return right  

test = range(10)
for i in range(10):
    random.shuffle(test)
    print random_selection(test, 0, len(test)-1, i)

以下是我在测试用例中收到的结果:

  

0
   1
   无
   3
   4
   无
   5
   4
   8
   没有

1 个答案:

答案 0 :(得分:2)

问题是你需要决定你的指数是基于0,还是基于开始。

除了递归调用random_selection之外,大多数代码都使用基于0的索引:

return random_selection(nums, pivot + 1, end, i - pivot)

将i索引调整为i - start(即假设索引基于开始)。

将此更改为:

return random_selection(nums, pivot + 1, end, i)

应该给出预期的结果。