排序 via F#

冒泡排序:

let rec bsort_asc s =
    let rec _bsort_asc = function
        |x1::x2::xs when x1 > x2 ->
            match _bsort_asc (x1::xs) with
                |None -> Some(x2::x1::xs)
                |Some xs2 -> Some(x2::xs2)
        |x1::x2::xs ->
            match _bsort_asc (x2::xs) with
                |None -> None
                |Some xs2 -> Some(x1::xs2)
        |_ -> None
    match _bsort_asc s with
        |None -> s
        |Some s2 -> bsort_asc s2

快速排序:

let rec quicksort = 
    function
    [] -> []
    |x::xs ->
        quicksort [for i in xs do if i < x then yield i]@
        x:: quicksort [for i in xs do if i >= x then yield i] 

插入排序

let rec insert x = function
    |[] -> [x]
    |y::tl when x > y -> y::(insert x tl)
    |l -> x::l
let rec insertion_sort alist =
    match alist with
        |[] -> []
        |x::tl -> insert x (insertion_sort tl)

希尔排序

let shellsort f a =
    let N = Array.length a - 1
    let mutable width = 1
    while width <= N do
        width <- 3 * width + 1
    width <- width / 3
    while width >= 1 do
        for i = width to N do
            let v = a.[i]
            let mutable j = i
            while j >= width && (f a.[j - width] v) > 0 do
                a.[j] <- a.[j-width]
                j <- j - width
            a.[j] <- v
let asc a b = (a - b)
let dec a b = (b - a)

直接选择排序

let rec ssort_asc alist =
    match alist with
        |[] -> []
        |l ->
            let minrest l =
                let rec aux list min acc =
                    match list with
                        [] -> min, acc
                        |h::t ->
                            if h < min then aux t h (min::acc)
                            else aux t min (h::acc)
                aux (List.tail l)(List.head l)[]
            let (min, rest) = minrest l
            min :: (ssort_asc rest)

堆排序

let swap (a:_ []) i j =
    let temp = a.[i]
    a.[i] <- a.[j]
    a.[j] <- temp
let sift cmp (a:_ []) start count =
    let rec loop root child =
        if root * 2 + 1 < count then
            let p = child < count - 1 && cmp a.[child] a.[child + 1] < 0
            let child = if p then child + 1 else child
            if cmp a.[root] a.[child] < 0 then
                swap a root child
                loop child (child * 2 + 1)
    loop start (start * 2 + 1)
let heapsort cmp (a:_ []) =
    let n = a.Length
    for start = n/2 - 1 downto 0 do
        sift cmp a start n
    for term = n - 1 downto 1 do
        swap a term 0
        sift cmp a 0 term
let asc a b = (a - b)
let dec a b = (b - a)

归并排序

let split list =
    let rec aux l acc1 acc2 =
        match l with
            |[] -> (acc1, acc2)
            |[x] -> (x::acc1, acc2)
            |x::y::tail -> aux tail (x::acc1) (y::acc2)
    aux list [] []
let rec merge l1 l2 =
    match (l1, l2) with
        |(x, []) -> x
        |([], y) -> y
        |(x::tx, y::ty) ->
            if x < y then x::merge tx l2
            else y::merge l1 ty
let rec mergesort list =
    match list with
        |[] -> []
        |[x] -> [x]
        |_ ->
            let (l1, l2) = split list
            merge (mergesort l1) (mergesort l2)

基数排序

let radixSort (list:int array) : int array =
    let largestInt = Array.maxBy abs list
    let largestIntLen = if largestInt = 0 then 1 else (int(log10 (abs(largestInt |> double))) + 1)
    for i = 0 to largestIntLen - 1 do
        let mutable buckets = Array.create 19 (List.empty<int>)
        for number in list do
            let nthDigit nth number = int(abs(number) / int(10. ** (float(nth)))) % 10
            let nth = nthDigit i number
            if number < 0 then
                buckets.[9 - nth] <- (List.append buckets.[9 - nth][number])
            elif number = 0 then
                buckets.[9 + nth] <- (List.append buckets.[9 + nth][number])
        let mutable listIndex = 0
        for bucket in buckets do
            for num in bucket do
                list.[listIndex] <- num
                listIndex <- listIndex + 1
    list
posted @ 2015-06-18 19:18 Johnwii 阅读(...) 评论(...) 编辑 收藏