26 lines
1.5 KiB
Forth
26 lines
1.5 KiB
Forth
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) [] // 将两部分分别归并排序,然后合并为有序数列 |