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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...