2013-10-07 54 views
1

這裏是quickselectPython的Quickselect不打印/返回轉動

def quickSelect(lst, k): 
if len(lst) != 0: 
    pivot = lst[(len(lst)) // 2] 
    smallerList = [] 
    for i in lst: 
     if i < pivot: 
      smallerList.append(i) 
    largerList = [] 
    for i in lst: 
     if i > pivot: 
      largerList.append(i) 
    count = len(lst) - len(smallerList) - len(largerList) 
    m = len(smallerList) 
    if k >= m and k < m + count: 
     return pivot 
     print(pivot) 
    elif m > k: 
     return quickSelect(smallerList, k) 
    else: 
     return quickSelect(largerList, k-m-count) 

的代碼,我與它遇到的問題是,它沒有任何錯誤或任何運行,但是當它完成了自己,我就期待輸出一些東西到Python shell(在這個特定的情況下,列表的中位數),但我沒有得到任何回報。我在這裏做錯了什麼?

至於什麼我輸入用於LST並且k ....

  • LST = [70,120,170,200]
  • K = LEN(LST)// 2

我有幾個不同的k值試過很好,但無濟於事

+0

可能只是差的格式,但你的縮進是錯誤的。在函數定義之後,您不會縮進。 –

+0

我剛剛運行它(固定縮進),並用你的輸入爲lst和k和quickSelect(lst,k)返回170.你能說你如何調用quickSelect和你的期望?嘗試打印(quickSelect(lst,k)))以確保解釋器打印結果。 –

回答

0
def quickSelect(lst, k): 
    if len(lst) != 0: 
     pivot = lst[(len(lst)) // 2] 
     smallerList = [] 
     for i in lst: 
      if i < pivot: 
       smallerList.append(i) 
     largerList = [] 
     for i in lst: 
      if i > pivot: 
       largerList.append(i) 
     count = len(lst) - len(smallerList) - len(largerList) 
     m = len(smallerList) 
     if k >= m and k < m + count: 
      return pivot 
      print(pivot) 
     elif m > k: 
      return quickSelect(smallerList, k) 
     else: 
      return quickSelect(largerList, k-m-count) 

lst = [70, 120, 170, 200] 
k = len(lst) // 2 

print(quickSelect(lst, k)) 

產生

>>> 170 

我糾正的唯一問題是縮進。

+0

「print(quickSelect(lst,k))」是我的問題。我打電話打印功能。當我像這樣跑它時,它工作。格式化實際上是正確的我只是複製+粘貼到這裏怪異。謝謝:) – BLU

3

您可以使用列表理解來優化此算法。此外,我不認爲你需要數...

def quickSelect(seq, k): 
    # this part is the same as quick sort 
    len_seq = len(seq) 
    if len_seq < 2: return seq 

    ipivot = len_seq // 2 
    pivot = seq[ipivot] 

    smallerList = [x for i,x in enumerate(seq) if x <= pivot and i != ipivot] 
    largerList = [x for i,x in enumerate(seq) if x > pivot and i != ipivot] 

    # here starts the different part 
    m = len(smallerList) 
    if k == m: 
     return pivot 
    elif k < m: 
     return quickSelect(smallerList, k) 
    else: 
     return quickSelect(largerList, k-m-1) 




if __name__ == '__main__': 
    # Checking the Answer 
    seq = [10, 60, 100, 50, 60, 75, 31, 50, 30, 20, 120, 170, 200] 

    # we want the middle element 
    k = len(seq) // 2 

    # Note that this only work for odd arrays, since median in 
    # even arrays is the mean of the two middle elements 
    print(quickSelect(seq, k)) 
    import numpy 
    print numpy.median(seq) 
+0

你的代碼非常好,但是如果'pivot'被簡單地定義爲'seq [0]',它就更簡單了。那麼你根本不需要使用'enumerate':'smallerList = [x for x in in seq [1:] if x <= pivot]'and'largerList = [x for x in seq [1:] if x>樞軸]'。 – cjauvin

+0

我們可以這樣做,但是我們需要小心的選擇主軸。例如,如果我們最終總是參與n-1個子陣列,則快速排序將具有運行時O(n^2)而不是O(nlogn)。在中間選擇樞軸並不能防止這種情況發生,但它比起初選擇樞軸的可能性更小。 – bt3gl