简体   繁体   English

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

[英]Understanding recursive functions - Quick select - Find Median in linear time

I am trying to implement this algorithm (from this site: https://sarielhp.org/research/CG/applets/linear_prog/median.html ). 我正在尝试实现此算法(从此站点: https : //sarielhp.org/research/CG/applets/linear_prog/median.html )。

FindKMedian( A, K ) // Return the number in A which is the K-th in its size. FindKMedian(A,K)//返回A中的数字,它是大小的第K个数字。

  1. Pick randomly a number a from A = {a1, ..., an}. 从A = {a1,...,an}中随机选择一个数字a。
  2. Partition the n numbers into two sets: 将n个数字分成两组:
    • S - all the numbers smaller than a S-所有小于a的数字
    • B - all the numbers bigger than a B-所有大于a的数字
  3. If |S| 如果| S | = K-1 then a is the required K-median. = K-1,则a是所需的K中值。 Return a 返回一个
  4. If |S| 如果| S | < K-1 then the K-median lies somewhere in B. Call recursively to FindKMedian( B, K - |S| - 1 ) <K-1,则K中值位于B中的某个位置。递归调用FindKMedian(B,K-| S |-1)
  5. Else, call recursively to FindKMedian( S, K ). 否则,递归调用FindKMedian(S,K)。

After @mikake answer I get an error calling the function with the parameters at the end of the code. @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))

I would expect the number 7 to come out from the return of quickselect (so quick_select(A, 5, 0, 9) means "find A[5] once the subarray A[0,...,5] is sorted or once A[5,...,9] is sorted "). 我希望数字7从quickselect的返回值中出来(所以quick_select(A,5,0,9)的意思是“一旦对子数组A [0,...,5]进行排序或一次查找A [5] A [5,...,9]排序为“)。 I probably didn't get what the semantic of this code should be. 我可能没有得到这段代码的语义。

Thank you 谢谢

You forgot to add the return statement in the "else" branches: 您忘记在“ 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)

I think the only error I made was not considering the case when the array has length 1. So the correct code of the function "quick_select" should be 我认为我犯的唯一错误是没有考虑数组长度为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)

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

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