diff --git a/.idea/.idea.Algorithm-FSharp/.idea/workspace.xml b/.idea/.idea.Algorithm-FSharp/.idea/workspace.xml index 9287c96..607b768 100644 --- a/.idea/.idea.Algorithm-FSharp/.idea/workspace.xml +++ b/.idea/.idea.Algorithm-FSharp/.idea/workspace.xml @@ -8,8 +8,7 @@ - - + @@ -96,7 +95,9 @@ - + + + 1660059459924 @@ -119,7 +120,14 @@ - @@ -144,6 +152,7 @@ - \ No newline at end of file diff --git a/Algorithm-FSharp/Algorithm-FSharp.fsproj b/Algorithm-FSharp/Algorithm-FSharp.fsproj index 8a95634..fe7fd8a 100644 --- a/Algorithm-FSharp/Algorithm-FSharp.fsproj +++ b/Algorithm-FSharp/Algorithm-FSharp.fsproj @@ -8,6 +8,7 @@ + diff --git a/Algorithm-FSharp/Program.fs b/Algorithm-FSharp/Program.fs index b1e6795..e08927a 100644 --- a/Algorithm-FSharp/Program.fs +++ b/Algorithm-FSharp/Program.fs @@ -1,8 +1,8 @@ // For more information see https://aka.ms/fsharp-console-apps module Algorithm_FSharp.Program -open Algorithm_FSharp.MergeSort +open Algorithm_FSharp.SelectionSort open Algorithm_FSharp.TestList // 测试用例 printfn $"%A{myList - |> mergesort}" + |> selection_sort}" diff --git a/Algorithm-FSharp/SelectionSort.fs b/Algorithm-FSharp/SelectionSort.fs new file mode 100644 index 0000000..3892a37 --- /dev/null +++ b/Algorithm-FSharp/SelectionSort.fs @@ -0,0 +1,36 @@ +module Algorithm_FSharp.SelectionSort +// 选择序列中的最小值 +// select_min_inner : 'a -> 'a list -> 'a +// cur中存储有当前的最小值 +let rec select_min_inner cur = function + | [] -> cur // 若序列中数已经用光,则返回cur + | x::xs -> // 若序列中还有数,则取出第一个数 + match x < cur with // 并将其和目前的最小值比较 + | true -> select_min_inner x xs // 若当前数小于目前的最小值,则将最小值更新为当前数 + | false -> select_min_inner cur xs // 若当前数大于等于目前最小值,则不更新最小值 + // 并继续在剩余元素中寻找 + +// select_min_inner的包装,可以方便的选择最小值 +// 会将序列的第一个元素作为目前的“最小值”传给select_min_inner +// select_min : 'T list -> 'T +let select_min (arr: 'T list) = select_min_inner arr.Head arr + +// 除去序列中不满足谓词的元素 +// remove_elem : ('a -> bool) -> 'a list -> 'a list +// 对每一个元素调用pred,若结果为假,则将此元素从序列中去除 +let rec remove_elem pred = function + | [] -> [] // 递归边界:若序列中没有元素,则什么都不用做 + | x::xs -> // 若序列中有其他元素 + match pred x with // 取出序列中第一个元素,并对其调用pred + | true -> x::(remove_elem pred xs) // 若返回值为真,则扫描剩余元素 + | false -> remove_elem pred xs // 若返回值为假,则去除此元素,并扫描剩余元素 +// 选择排序的F#实现 +// selection_sort : 'a list -> 'a list +let rec selection_sort = function + | [] -> [] // 若待排序序列为空或只有一个元素,则它已经有序,直接返回 + | [single] -> [single] + | xs -> // 若待排序序列含有不止一个元素 + let min = select_min xs // 选出最小值 + let rest = xs // 将最小值从序列中移除 + |> remove_elem (fun x -> x <> min) + min::(selection_sort rest) // 对剩余部分进行递归排序,将最小值附加在排序结果的首部 \ No newline at end of file