【问题标题】:What is the most elegant way of bubble-sorting in F#?F# 中最优雅的冒泡排序方式是什么?
【发布时间】:2010-09-21 16:54:07
【问题描述】:

F# 中最优雅的冒泡排序方式是什么?

更新

正如其中一个答案所指出的,冒泡排序在函数式语言中一开始就不是有效的。一位幽默而愤世嫉俗的评论者还指出,冒泡排序仅适用于列表很小且几乎已排序的情况。

但是,我很想知道如何用 F# 编写聪明的冒泡排序,因为我过去曾在 C#、C++ 和 Java EE 中进行过冒泡排序,而且我是 F# 新手.

【问题讨论】:

  • +1 表示在同一个句子中使用“优雅”和“冒泡排序”这两个词的幽默感
  • 如果集合很小,冒泡排序是有效的,并且几乎是排序的。
  • F#,优雅?哈哈,幽默+1。

标签: algorithm sorting f#


【解决方案1】:

在函数式语言中使用冒泡排序不是很有效,因为实现必须多次反转列表(对于不可变列表,这不能真正有效地实现)。

无论如何,Erlang 中的示例可以像这样重写为 F#:

let sort l = 
  let rec sortUtil acc rev l =
    match l, rev with
    | [], true -> acc |> List.rev
    | [], false -> acc |> List.rev |> sortUtil [] true
    | x::y::tl, _ when x > y -> sortUtil (y::acc) false (x::tl)
    | hd::tl, _ -> sortUtil (hd::acc) rev tl
  sortUtil [] true l

另一方面,您可以使用可变数组实现相同的算法。这将更有效率,并且在 F# 中,如果需要,您也可以使用数组。以下函数创建数组的副本并对其进行排序。

let sort (arr:'a[]) = 
  let arr = arr |> Array.copy
  let swap i j = let tmp = arr.[i] in arr.[i] <- arr.[j]; arr.[j] <- tmp
  for i = arr.Length - 1 downto 0 do
    for j = 1 to i do
      if (arr.[j - 1] > arr.[j]) then swap (j-1) j
  arr

托马斯

【讨论】:

【解决方案2】:

F# 是一种不纯的语言。不要拘泥于纯洁。这是 F# 中更简单、更优雅的不纯冒泡排序:

let rec sort (a: int []) =
  let mutable fin = true
  for i in 0..a.Length-2 do
    if a.[i] > a.[i+1] then
      let t = a.[i]
      a.[i] <- a.[i+1]
      a.[i+1] <- t
      fin <- false
  if not fin then sort a

【讨论】:

    猜你喜欢
    • 2010-12-08
    • 1970-01-01
    • 2015-09-12
    • 2013-04-18
    • 2017-03-02
    • 2010-12-08
    • 2013-03-09
    • 2012-07-13
    • 2015-09-16
    相关资源
    最近更新 更多