【问题标题】:Understanding recursive functions - Quick select - Find Median in linear time了解递归函数 - 快速选择 - 在线性时间内查找中位数
【发布时间】:2019-06-03 09:43:06
【问题描述】:

我正在尝试实现此算法(来自此站点: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 的返回中出来(所以 quick_select(A, 5, 0, 9) 的意思是“一旦子数组 A[0,...,5] 是找到 A[5]排序或一旦 A[5,...,9] 排序“)。我可能没有明白这段代码的语义应该是什么。

谢谢

【问题讨论】:

标签: python algorithm sorting quicksort quickselect


【解决方案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)

【讨论】:

  • @Franco - 你应该澄清你用你的答案解决了这个问题(处理数组长度== 1),或者只是删除你的评论。我稍后会删除此评论。
【解决方案2】:

我认为我犯的唯一错误是没有考虑数组长度为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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    • 2015-11-14
    • 2012-11-17
    • 1970-01-01
    • 1970-01-01
    • 2013-06-06
    • 2016-04-09
    相关资源
    最近更新 更多