【问题标题】:Haskell Bubble Sort on a three part TupleHaskell 冒泡排序在三部分元组上
【发布时间】:2013-03-19 03:46:18
【问题描述】:

我正在尝试实施冒泡排序来按优先级对列表进行排序。例如,列表具有以下格式,第 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

【问题讨论】:

  • 您的函数对整个元组进行排序,因此如果您希望它对元组的第三个元素进行排序,则需要修改一些内容。顺便说一句,永远不要使用冒泡排序。
  • @augustss 我可以在冒泡排序上使用什么?插入排序?为什么我不应该使用冒泡排序?
  • 只是冒泡排序效率极低。
  • @user2214957,因为它很慢。顺便说一句,如果这不仅仅是一个实验,看看你是否可以实现排序算法,你可能想看看Data.List.sortBy
  • @luqui 老实说,我只是将其用作学习曲线。在这个阶段它并不意味着高效。

标签: haskell bubble-sort


【解决方案1】:

正如 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 )

并在以后关心更精细的订单。

【讨论】:

  • 谢谢。如果切换列表元素以使优先级位于第一个位置,那么我上面问题中的基本代码应该可以正常工作吗?排序将在它找到的第一个项目上运行?。
  • 它将在Ord 实例定义的任何内容上运行。在 3 元组的情况下,这恰好是:第一个元素的优先级,然后是第二个,然后是第三个,然后是 EQ
猜你喜欢
  • 1970-01-01
  • 2016-02-10
  • 1970-01-01
  • 2020-04-08
  • 2013-09-28
  • 1970-01-01
  • 2020-09-28
  • 2018-08-06
相关资源
最近更新 更多