如何解决OCAML尾递归合并排序
我有一些用OCaml编写的代码,我试图创建一个接受列表并通过合并排序对其进行排序的函数。
let rec msort ls =
let rec split lst (l1,l2) = match lst with
| [] -> (l1,l2)
| h::t -> split t (l2,h::l1) in
let merge l1 l2 =
let rec mergemerge l1 l2 acc = match (l1,l2) with
| (_,[]) -> l1
| ([],_) -> l2
| [],[] -> acc
| (h1::t1,h2::t2) -> if h1 < h2 then mergemerge t1 l2 (h1 :: acc)
else mergemerge l1 t2 (h2 :: acc)
in List.rev (mergemerge l1 l2 [])
in
let (l1,l2) =
split ls ([],[]) in merge (msort l1) (msort l2);;
当我尝试编译代码时,它说“评估期间堆栈溢出(循环递归?)。”我想知道如何更改主体,以使其不会无限递归,并且想知道如何以及在哪里向主体添加基本案例。谢谢!
解决方法
无论输入列表是什么样,您的函数都会递归调用自身。因此,这将导致无限递归。
正如您所说,您需要检查基本情况。
此功能的基本情况很容易看到:是否已对任何输入列表进行排序?是的,已经对空列表和仅包含一个元素的列表进行了排序。
添加一个if ... then ... else
作为msort
的最外面的表达式。它应该测试基本情况并在这种情况下返回明显的结果。在其他情况下,它应该执行现在的操作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。