我正在尝试实施冒泡排序,以按优先级排序我的列表。例如,列表具有以下格式,第3个元素为优先级:
[("Ted", 100, 3), ("Boris", 100, 1), ("Sam", 100, 2)]
我已尝试过下面的标准冒泡排序方法,但这不起作用。任何建议,将不胜感激。
bubbleSort :: (Ord t) => [t] -> [t]
bubbleSort a = loop (length a) bubble a
bubble :: (Ord t) => [t] -> [t]
bubble (a:b:c) | a < b = a : bubble (b:c)
| otherwise = b : bubble (a:c)
bubble (a:[]) = [a]
bubble [] = []
loop :: (Num a, Ord a) => a -> (t -> t) -> t -> t
loop num f x | num > 0 = loop (num-1) f x'
| otherwise = x
where x' = f x
答案 0 :(得分:5)
正如luqui所暗示的那样,直接实现排序算法的Ord
约束版本是正常的,但更常用的是使用自定义比较:
bubbleSortBy :: (t->t->Ordering) -> [t] -> [t]
bubbleSortBy cmp a = loop (length a) bubble a
where
bubble :: (Ord t) => [t] -> [t]
bubble (a:b:c) = case cmp a b of
LT -> a : bubble (b:c)
_ -> b : bubble (a:c)
bubble l = l
loop :: Integral a -- (Num, Ord) is a bit /too/ general here, though it works.
=> a -> (t -> t) -> t -> t
loop num f x | num > 0 = loop (num-1) f x'
| otherwise = x
where x' = f x
Ord
版本可以通过以下方式实现:
bubbleSort :: (Ord t) -> [t] -> [t]
bubbleSort = bubbleSortBy compare
但直接使用通用版本通常更为实际,例如在您的情况下
import Data.Function(on)
sorted_priority3rd = bubbleSortBy ( compare `on` \(a,b,c) -> (c,a,b) )
这样做,它会在每次比较之前改变参数的顺序。显然,这使得泡沫排序更慢;通常你宁愿做
import Data.List (sortBy) -- this is a proper ( log ) sorting algorithm
sorted_by3rd = sortBy ( compare `on` \(a,b,c) -> c )
稍后关心更精细的订单。