簡體   English   中英

Haskell中的quicksort如何工作?

[英]How does quicksort in Haskell work?

Haskell網站上 ,這個示例是quicksort實現

quicksort :: Ord a => [a] -> [a]
quicksort []     = []
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
    where
        lesser  = filter (< p) xs
        greater = filter (>= p) xs

該網站有一個解釋,但我有幾個問題,我沒有看到解決...

  • 對於重新訂購,兩個元素的實際比較/交換在哪里? 這是由'Ord'(有序)類型定義本身處理的。 那么類型強制執行這個被命令的條件?
  • “更大”的過濾器定義了項目'> = p'(樞軸),所以這並不意味着我們最終會在函數的結果列表中有一個額外的pivot [p],因為'++ [p ]'項目?
  1. 沒有交換,因為這不是QS的(幾乎)就地版本。 相反,新的名單是建立,然后再連接-當比較完成lessergreater的創建,以<>= - Ord是一個類型類限制a要訂購-如果沒有使用它,你就不能使用<>=
  2. 不,因為樞軸不是xs一部分 - 模式匹配將輸入列表拆分為pxs

這是糟糕的ASCII可視化:

                                qs [5, 5, 6, 3, 1]
                                          |
                         qs [3, 1]   ++  [5] ++ qs [5, 6]
                             |            |       |
                  qs [1] ++ [3] ++ qs []  |    qs [] ++ [5] ++ qs [6]
                             |            |       |
                           [1, 3]    ++  [5]  ++ [5, 6]
                             \            |        /
                              \-------------------/
                                        |
                                  [1, 3, 5, 5, 6]

對於重新訂購,兩個元素的實際比較/交換在哪里? 這是由Ord (有序)類型定義本身處理的。 那么類型強制執行這個被命令的條件?

Ord是什么意思?

Ord只是意味着a應該與自身相比或者更嚴格的術語,例如><==應該為a定義。 您可以將其視為該方法的約束。

那么,訂購在哪里完成?

答案是最后一種模式:

quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
    where
        lesser  = filter (< p) xs
        greater = filter (>= p) xs

在運行時,程序將獲得一個數組,並且數組必須滿足以下兩種模式之一:

模式1#:它是空的,在這種情況下,該函數返回相同的空數組並停止。

模式2#:它不是空的,換句話說,有一個頭元素p附加到尾部數組xs 在這樣的情況下,函數被告知把p在中間,放的所有元素xs是小於p的左(通過定義lesser )的p和的所有元素xs是大於或等於p在右邊的p 此外,最后告訴函數將自身(即,相同的函數quicksort )應用於lesser (如上所述,是p的左側的數組)和greater (正如我們在上面定義的那樣,是數組)在p )的右側。 正如您所看到的,這將持續到您留下零大小的數組並且模式1#終止該函數。

最后,每當這些遞歸調用終止時,函數都將返回數組:

sortedlesser ++ p ++ sortedgreater 

其中sortedlesser是起因於應用的陣列quicksortlesser並且sortedgreater是起因於應用的陣列quicksortgreater

等等......我們不是一次又一次地復制p嗎?

'更大'的謂詞定義了項'> = p'(樞軸),所以這並不意味着我們最終會在函數的結果列表中得到一個額外的pivot [p],因為'++ [p ]'項目?

不,這不是模式匹配的工作原理。 它說xs中的所有元素都大於或等於p 根據定義, p本身不在xs 如果在xs有重復的p ,那么它們將落在右側。 請注意,此選擇將​​保留原始數組的自然順序。

請注意,您可以使用更短更高效的內容(因為partition僅掃描原始列表一次)

quicksort [] = []
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
    where (lesser, greater) = partition (< p) xs

如果您只想要一行:

qsortOneLine s = case s of{[]->[];(x:xs)->qsortOneLine [y | y<-xs, y<x] ++ x : qsortOneLine [y | y<-xs, y>=x]}

如果您想要更高性能的代碼:

qsort3 :: Ord a => [a] -> [a]
qsort3 x = qsort3' x []
qsort3' [] y     = y
qsort3' [x] y    = x:y
qsort3' (x:xs) y = part xs [] [x] []  
      where
         part [] l e g = qsort3' l (e ++ (qsort3' g y))
         part (z:zs) l e g 
             | z > x     = part zs l e (z:g) 
             | z < x     = part zs (z:l) e g 
             | otherwise = part zs l (z:e) g

http://en.literateprograms.org/Quicksort_(Haskell

暫無
暫無

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

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