haskell 基础题解(24)

归并排序

【题目】归并排序是在两个已经排序的队列中,不断取队头最小的来完成排序的一种算法。试模拟其 merge 算法。

这个问题用 haskell 解决很容易。haskell 的惰性又可以免去我们考虑队列过大的问题。
因为焦点是在列表上进行运算,haskell写起来更容易看出算法的本质,而不被无关的语法细节所遮避。

----简单归并排序
import Data.List (splitAt)

gui_bing :: Ord a => [a] -> [a]
gui_bing [] = []
gui_bing [x] = [x]
gui_bing da = f (gui_bing partA) (gui_bing partB)
    where
    n = length da `div` 2
    (partA, partB) = splitAt n da
    f [] ys = ys
    f xs [] = xs
    f (x:xs) (y:ys) | x < y     = x : f xs (y:ys)
                    | otherwise = y : f (x:xs) ys

main = getLine >>= putStrLn . gui_bing

列表被对分成两半,分别排序后,再进行 merge过程。
merge的时候,如一边为空,则另一边直接为结果。
否则取出两队中头元素的较小者,剩下的递归 merge 过程。

这里的 getLine 取出的是一个字符串。而在 haskell 中字符串只是字符的列表,即: String = [Char], 而 Char 是可比较的类型,因而字符串可以对其中的字符重新排序。每个字符的比较则按它们的 unicode 码序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值