You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell通用快速排序实现:如何适配任意类型列表?

支持任意类型的自定义比较快速排序

当然可以修改这个算法,让它支持任意类型的列表,核心思路就是把原本依赖Ord类型类的比较逻辑,作为额外参数传入函数中,完全由调用者定义排序规则。

修改后的实现(基于布尔比较函数)

这个版本接受一个a -> a -> Bool类型的函数,用来判断第一个元素是否应该排在第二个元素的前面(对应原逻辑中的“小于等于基准值”):

quicksort :: (a -> a -> Bool) -> [a] -> [a]
quicksort _ [] = []
quicksort shouldComeBefore (x:xs) =
    let smallerSorted = quicksort shouldComeBefore (filter (\y -> shouldComeBefore y x) xs)
        biggerSorted = quicksort shouldComeBefore (filter (\y -> not (shouldComeBefore y x)) xs)
    in smallerSorted ++ [x] ++ biggerSorted

使用示例

  • 还原原算法的整数排序:
    -- 传入(<=)函数,和原快排行为完全一致
    quicksort (<=) [3,1,4,1,5,9,2,6]
    
  • 自定义类型排序(比如按Person的年龄或名字排序):
    data Person = Person { name :: String, age :: Int } deriving Show
    
    -- 按年龄升序排序
    sortByAge :: [Person] -> [Person]
    sortByAge = quicksort (\p1 p2 -> age p1 <= age p2)
    
    -- 按名字字典序排序
    sortByName :: [Person] -> [Person]
    sortByName = quicksort (\p1 p2 -> name p1 <= name p2)
    

更通用的Ordering版本

如果需要更精细的比较逻辑(比如区分等于、小于、大于),可以改用返回Ordering类型的比较函数,逻辑更清晰:

quicksort :: (a -> a -> Ordering) -> [a] -> [a]
quicksort _ [] = []
quicksort compareFn (x:xs) =
    let smallerSorted = quicksort compareFn (filter (\y -> compareFn y x /= GT) xs)
        biggerSorted = quicksort compareFn (filter (\y -> compareFn y x == GT) xs)
    in smallerSorted ++ [x] ++ biggerSorted

调用时可以直接用标准库的compare函数(对于实现了Ord的类型),或者自定义比较逻辑:

-- 整数降序排序
quicksort (\a b -> compare b a) [3,1,4,1,5]

核心变化说明

原算法依赖Ord a约束,只能处理实现了默认排序逻辑的类型;修改后的版本去掉了这个约束,把排序规则完全交给传入的比较函数,因此可以处理任意类型,只要调用者提供对应的比较逻辑即可。

内容的提问来源于stack exchange,提问作者dumbQuestions

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 22:40:33