Algorithm-FSharp/Algorithm-FSharp/MergeSort.fs

26 lines
1.5 KiB
Forth
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

module Algorithm_FSharp.MergeSort
// 合并有序数列算法
// merge : 'a list -> 'a list -> 'a list -> 'a list
// 待合并的有序数列存储在lhs和rhs中每一步合并后中间结果都存放在res中
let rec merge lhs rhs res =
match (lhs, rhs) with // 判断lhs和rhs是否为空
| [], [] -> res // 若两者均为空直接返回res
| [], ys -> res @ ys // 若lhs中的数已经用光则将rhs追加到res末尾并返回
| xs, [] -> res @ xs // 若rhs中的数已经用光则将lhs追加到res末尾并返回
| x::xs, y::ys -> // 若二者均不为空
match x < y with // 取出第一个元素,并判断二者的大小关系
| true -> merge xs (y::ys) (res @ [x]) // 若lhs的第一个元素小于rhs的第一个元素则将其取出并放置在res的末尾递归合并剩余的元素
| false -> merge (x::xs) ys (res @ [y]) // 若rhs的第一个元素小于lhs的第一个元素则将其取出并放置在res的末尾递归合并剩余的元素
// 归并排序算法的F#实现
// mergesort : 'a list -> 'a list
let rec mergesort arr =
match arr with // 模式匹配
| [] -> [] // 若arr为空或只有一个元素则它已经有序直接返回
| [single] -> [single]
| _ -> // 若arr的元素多于一个
let mid = arr.Length / 2 // 计算序列中点的索引
let left, right = arr // 从中点切分序列为两部分
|> List.splitAt mid
merge (mergesort left) (mergesort right) [] //