簡體   English   中英

如何在 Quickselect 中實現 Hoare 分區方案?

[英]How to implement the Hoare partition scheme in Quickselect?

我嘗試將Hoare 分區方案作為 Quickselect 算法的一部分來實現,但它似乎每次都給我各種答案。

這是findKthBest函數,它在給定數組 ( data ) 和其中元素的數量的情況下查找數組中的第 K 個最大數(如果為 5 個元素, findKthBest low = 0high = 4 ):

def findKthBest(k, data, low, high):
    # choose random pivot
    pivotindex = random.randint(low, high)

    # move the pivot to the end
    data[pivotindex], data[high] = data[high], data[pivotindex]

    # partition
    pivotmid = partition(data, low, high, data[high])

    # move the pivot back
    data[pivotmid], data[high] = data[high], data[pivotmid]

    # continue with the relevant part of the list
    if pivotmid == k:
        return data[pivotmid]
    elif k < pivotmid:
        return findKthBest(k, data, low, pivotmid - 1)
    else:
        return findKthBest(k, data, pivotmid + 1, high)

函數partition()有四個變量:

  • data (一個列表,例如 5 個元素),
  • l (列表中相關部分的起始位置,例如0)
  • r (列表中相關部分的結束位置,也就是樞軸所在的位置,例如 4)
  • pivotpivot的值)
def partition(data, l, r, pivot):
    while True:
        while data[l] < pivot:
            #statistik.nrComparisons += 1
            l = l + 1
        r = r - 1    # skip the pivot
        while r != 0 and data[r] > pivot:
            #statistik.nrComparisons += 1
            r = r - 1
        if r > l:
            data[r], data[l] = data[l], data[r]
        return r

現在我只是每次都得到不同的結果,似乎遞歸不能很好地工作(有時它以達到最大遞歸錯誤結束),而不是每次都給出一個恆定的結果。 我究竟做錯了什么?

首先,函數partition()似乎有錯誤

如果您仔細將您的代碼與 wiki 中的代碼進行比較,您會發現不同之處。 功能應該是:

def partition(data, l, r, pivot):
    while True:
        while data[l] < pivot:
            #statistik.nrComparisons += 1
            l = l + 1
        r = r - 1    # skip the pivot
        while r != 0 and data[r] > pivot:
            #statistik.nrComparisons += 1
            r = r - 1
        if r >= l:
            return r

        data[r], data[l] = data[l], data[r]

二、舉例:

  • 分區后得到一個數組data = [1, 0, 2, 4, 3]pivotmid=3
  • 您想找到第 4 個最大值 ( k=4 ),即 1

findKthBest()的下一個數組data解析將變為[1, 0]
因此,下一個findKthBest()應該找到數組[1, 0]最大值:

def findKthBest(k, data, low, high):
    ......

    # continue with the relevant part of the list
    if pivotmid == k:
        return data[pivotmid]
    elif k < pivotmid:
        #Corrected
        return findKthBest(k-pivotmid, data, low, pivotmid - 1)
    else:
        return findKthBest(k, data, pivotmid + 1, high)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM