F#使用head::tail进行排序
我正在尝试编写一个使用head::tail的递归函数。我知道列表第一个元素中的head和tail是列表中的所有其他元素。我也理解递归是如何工作的。我想知道的是如何对列表中的元素进行排序。有没有办法将头部与尾部的每个元素进行比较,然后选择最小的元素?我的背景是C++,我不允许使用列表。你知道怎么做吗?我已经看过msdn网站上的教程,但仍然不走运在担心使用的数据结构之前,您需要确定一种排序方法。如果要执行(比如)插入排序,可能需要从列表的末尾开始,在每个递归级别插入一个项,注意如何处理插入本身 从技术上讲,在任何特定级别上,您只能访问一个数据元素,但是您可以将特定数据元素作为参数传递以保留它。例如,这里是插入排序算法的插入部分,它假定列表已排序F#使用head::tail进行排序,f#,tail-recursion,F#,Tail Recursion,我正在尝试编写一个使用head::tail的递归函数。我知道列表第一个元素中的head和tail是列表中的所有其他元素。我也理解递归是如何工作的。我想知道的是如何对列表中的元素进行排序。有没有办法将头部与尾部的每个元素进行比较,然后选择最小的元素?我的背景是C++,我不允许使用列表。你知道怎么做吗?我已经看过msdn网站上的教程,但仍然不走运在担心使用的数据结构之前,您需要确定一种排序方法。如果要执行(比如)插入排序,可能需要从列表的末尾开始,在每个递归级别插入一个项,注意如何处理插入本身 从技
let rec insert i l =
match l with
| [] -> [i]
| h::t -> if h > i then
i::l
else
h::(insert i t)
请注意,我现在可以访问两个元素,一个是缓存的元素,另一个是剩余的元素。另一种变体是合并排序,其中有两个已排序的列表,因此有两个项用于任何特定迭代
如果您感兴趣,Daniel的评论回答会提到一个特定的实现(快速排序)
最后,列表由于其刚性结构和所需的分配数量,对于排序算法来说不是最优的。考虑到所有已知排序算法的复杂性都大于O(n),您可以在不影响渐进性能的情况下将列表转换为数组和从数组转换列表,以提高性能
编辑:请注意,以上不是尾部递归格式,您需要执行以下操作:
let insert i l =
let rec insert i l acc =
match l with
| [] -> List.foldBack (fun e a -> e :: a) acc [i]
| h::t -> if h > i then
List.foldBack (fun e a -> e :: a) acc i::l
else
insert i l (i::acc)
insert i l []
我一时记不起反转列表的最佳方法,因此使用了中的一个示例,在担心使用的数据结构之前,您需要确定一种排序方法。如果要执行(比如)插入排序,可能需要从列表的末尾开始,在每个递归级别插入一个项,注意如何处理插入本身 从技术上讲,在任何特定级别上,您只能访问一个数据元素,但是您可以将特定数据元素作为参数传递以保留它。例如,这里是插入排序算法的插入部分,它假定列表已排序
let rec insert i l =
match l with
| [] -> [i]
| h::t -> if h > i then
i::l
else
h::(insert i t)
请注意,我现在可以访问两个元素,一个是缓存的元素,另一个是剩余的元素。另一种变体是合并排序,其中有两个已排序的列表,因此有两个项用于任何特定迭代
如果您感兴趣,Daniel的评论回答会提到一个特定的实现(快速排序)
最后,列表由于其刚性结构和所需的分配数量,对于排序算法来说不是最优的。考虑到所有已知排序算法的复杂性都大于O(n),您可以在不影响渐进性能的情况下将列表转换为数组和从数组转换列表,以提高性能
编辑:请注意,以上不是尾部递归格式,您需要执行以下操作:
let insert i l =
let rec insert i l acc =
match l with
| [] -> List.foldBack (fun e a -> e :: a) acc [i]
| h::t -> if h > i then
List.foldBack (fun e a -> e :: a) acc i::l
else
insert i l (i::acc)
insert i l []
我不记得立即反转列表的最佳方法,因此使用了中的一个示例,这里是F中基于递归列表的快速排序算法的实现#
让rec快速排序列表=
匹配列表
| [] -> []
|h::t->
设lesser=List.filter(>)h)t
让bether=List.filter((这里是F中基于列表的快速排序算法的递归实现#
让rec快速排序列表=
匹配列表
| [] -> []
|h::t->
设lesser=List.filter(>)h)t
让更大的=List.filter((谢谢,我查了f#排序,找不到那一个汉克,我查了f#排序,找不到那一个汉克你,只是一个跟进,如果这对新手来说很抱歉,但我是f#新手。在我的程序中,我使用随机数生成我的列表。code//let nonList=randomNumberList 10//。我如何将正确的参数传递给insert函数。我注意到insert有两个参数,但我只有一个参数要传递?据我所知,这不利于尾部调用,所以请注意careful@user1623521:这是正确的,如果您希望它处于尾部调用形式,您需要使用累积列表对其进行转换。我将它保留为非尾部调用友好型,因为我发现尾部调用为当我只关注递归方法时,我有时会感到困惑。@user1623521:因为执行转换很困难,因为在获得插入位置之前,我添加了一个向后建立列表前缀部分列表的方法,然后在前面将其反转。谢谢,只是一个后续操作,如果它看起来不正确,我很抱歉ice但我对F#不熟悉。在我的程序中,我使用随机数生成列表。code//let nonList=randomNumberList 10//。我如何将正确的参数传递给insert函数。我注意到insert有两个参数,但我只有一个参数要传递?据我所知,这不利于尾部调用,所以请小心ul@user1623521:这是正确的,如果您想让它成为尾部调用形式,您需要使用累积列表对其进行转换。我将其保留为非尾部调用友好型,因为我发现在简单地关注递归方法时,尾部调用形式有时会令人困惑。@user1623521:因为在我添加了否决票的情况下,执行转换很困难一旦我们有了插入位置,在前面反转它们之前,建立列表前缀部分的向后列表。这个尾部调用友好吗?这个尾部调用友好吗?