问题描述
我有一些用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
的最外面的表达式。它应该测试基本情况并在这种情况下返回明显的结果。在其他情况下,它应该执行现在的操作。