haskell快速排序,为什么第一个让使用&lt; =而不是<! - ? - >

时间:2015-03-08 02:45:20

标签: list sorting haskell

quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs) =
    let smallerOrEqual = [a | a <- xs, a <= x]
        larger = [a | a <- xs, a > x]
    in quicksort smallerOrEqual ++ [x] ++ larger

main = do
    let a = [ 5, 1, 9, 4, 6, 7, 3]
    print  $ quicksort a

在Haskell快速排序中,为什么第一个let使用<=而不是<?我认为<=会多次复制x次。为什么不呢?

1 个答案:

答案 0 :(得分:5)

  

我认为&lt; =会多次复制那个x

不,它不会。让我们了解这里到底发生了什么。您基本上将列表分为三个部分。

  1. 小于或等于pivot元素的数字列表(不包括第一个元素,因为它是pivot元素)

  2. 枢轴元素本身(列表中的第一个元素)

  3. 大于枢轴元素的数字列表

  4. 因此,在您的情况下,分区列表就像这样

    [1, 4, 3] ++ [5] ++ [9, 6, 7]
    

    考虑这样的案例,quicksort [5, 1, 5, 9, 8, 5, 3, 6, 4]。然后,您的程序会将其分区为这样的

    smallerOrEqual ++ [x] ++ larger
    

    由于smallerOrEquallarger使用的xs没有x,因此没有重复。现在,过滤后的分区列表变为

    [1, 5, 5, 3, 4] ++ [5] ++ [9, 8, 6]
    

    请参阅?没有重复,只是分区。

    注意:您的程序存在严重错误。检查此行

    quicksort smallerOrEqual ++ [x] ++ larger
    

    它基本上像这样工作

    (quicksort smallerOrEqual) ++ [x] ++ larger
    

    因此,larger列表永远不会排序。您递归地必须对较小的列表和较大的列表进行排序,最后将它们合并为一个。所以,应该是

    (quicksort smallerOrEqual) ++ [x] ++ (quicksort larger)
    

    可以在没有像这样的括号的情况下编写

    quicksort smallerOrEqual ++ [x] ++ quicksort larger