了解递归函数-快速选择-在线性时间内查找中位数

时间:2019-06-03 09:43:06

标签: python algorithm sorting quicksort quickselect

我正在尝试实现此算法(来自此站点:https://sarielhp.org/research/CG/applets/linear_prog/median.html)。

FindKMedian(A,K) //返回A中的数字,其大小为第K个数字。

  1. 从A = {a1,...,an}中随机抽取一个数字a。
  2. 将n个数字分成两组:
    • S-所有小于a的数字
    • B-所有大于a的数字
  3. 如果| S | = K-1,则a是所需的K中值。返回一个
  4. 如果| S |
  5. 否则,递归调用FindKMedian(S,K)。

@mikake回答后,我在调用代码末尾带有参数的函数时遇到错误。

import random


def quick_select(A, k, s, d):
    r = random.choice(range(s, d))
    pivot = partition(A, r, s, d)
    if pivot == k:
        return A[pivot]
    elif k < pivot:
        return quick_select(A, k, s, pivot-1)
    else:
        return quick_select(A, k, pivot + 1, d)


def partition(A, r, s, d):
    j = s-1
    assert s <= r
    assert r <= d
    temp = A[d]
    A[d] = A[r]
    A[r] = temp
    for i in range(s, d):
        if A[i] <= A[d]:
            j = j+1
            temp = A[j]
            A[j] = A[i]
            A[i] = temp
    j = j+1
    temp = A[j]
    A[j] = A[d]
    A[d] = temp
    return j


random.seed(0)
A = [4, 7, 7, 2, 2, 0, 9, 8, 1, 8]
print(quick_select(A, 5, 0, 9))

我希望数字7从quickselect的返回值中出来(因此,一旦子数组A [0,...,5]是,则quick_select(A,5,0,9)的意思是“找到A [5]”排序,或者将A [5,...,9]排序一次)。我可能没有得到这段代码的语义。

谢谢

2 个答案:

答案 0 :(得分:1)

您忘记在“ else”分支中添加return语句:

def quick_select(A, k, s, d):
    r = random.choice(range(s, d))
    pivot = partition(A, r, s, d)
    if pivot == k:
        return A[pivot]
    elif k < pivot:
        return quick_select(A, k, s, pivot-1)
    else:
        return quick_select(A, k, pivot + 1, d)

答案 1 :(得分:0)

我认为我犯的唯一错误不是考虑数组长度为1的情况。因此,函数“ quick_select”的正确代码应该是

def quick_select(A, k, s, d):
    if s == d:
        return A[k]
    r = random.choice(range(s, d))
    pivot = partition(A, r, s, d)
    if pivot == k:
        return A[pivot]
    elif k < pivot:
        return quick_select(A, k, s, pivot-1)
    else:
        return quick_select(A, k, pivot + 1, d)