代码之家  ›  专栏  ›  技术社区  ›  Kaiser Advisor

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

  •  8
  • Kaiser Advisor  · 技术社区  · 16 年前

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

    使现代化

    正如其中一个答案所指出的,冒泡排序在函数式语言中一开始就没有效率。一位幽默而愤世嫉俗的评论者还指出,只有当列表很小且几乎已排序时,冒泡排序才是合适的。

    然而,我很好奇,看看在F~()中如何编写一个聪明的冒泡排序,因为我过去在C语言、C++和JavaEE中已经完成了冒泡排序,因为我是一个F.java新手。

    1 回复  |  直到 11 年前
        1
  •  12
  •   Tomas Petricek    16 年前

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

    无论如何,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
  •  2
  •   J D    5 年前

    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