Ocaml插入排序

Ocaml插入排序,ocaml,Ocaml,输入:未排序列表/输出:已排序列表 我的基本想法是在排序列表中插入一个整数 (如果可以将第一个元素插入已排序的尾部,则可以对列表进行排序。) 我使用了“insert”,这是helper函数 但是,它会溢出。有人能告诉我问题出在哪里吗 let rec sort (l: int list) : int list = match l with []->[] | x::[]->[x] | x1::x2::xs->let rec inser

输入:未排序列表/输出:已排序列表

我的基本想法是在排序列表中插入一个整数

(如果可以将第一个元素插入已排序的尾部,则可以对列表进行排序。)

我使用了“insert”,这是helper函数

但是,它会溢出。有人能告诉我问题出在哪里吗

let rec sort (l: int list) : int list =
    match l with
        []->[]
      | x::[]->[x]
      | x1::x2::xs->let rec insert (n,dest) =
                            match dest with
                                []->[n]
                              | y::[]-> if n<y then [n;y] else [y;n]
                              | y1::y2::ys-> if y1<y2 then n::dest else y2::insert(y1,xs)
                    in insert(x1,sort(x2::xs)) ;;
让rec排序(l:int-list):int-list=
匹配
[]->[]
|x::[]->[x]
|x1::x2::xs->let rec insert(n,dest)=
匹配目标
[]->[n]

|y::[]->如果n如果y1我觉得这行非常错误:

| y1::y2::ys-> if y1<y2 then n::dest else y2::insert(y1,xs)

| y1::y2::ys->如果y1再次出现,我有一些风格建议:

  • 您应该将这两个函数
    sort
    insert
    分开,因为这会使它更可读,而且
    insert
    函数本身也很有用
  • 为什么要给
    insert
    函数一个元组作为参数?在OCaml中,可以使用curry和write
    insertxl
    代替
    insert(x,l)
    。这将允许您执行部分应用程序
  • 为什么将函数类型限制为
    int list->int list
    。OCaml中的函数可以是多态的,因此您的函数应该具有更通用的类型
    'a ist->'a list
以下是您通过所有这些更正获得的代码:

let rec insert x l =
  match l with
    | [] -> [x]
    | y::ys -> if x < y then x::y::ys else y::insert x ys

let rec sort l =
  match l with
    | [] -> []
    | x::xs -> insert x (sort xs)
让rec插入x l=
匹配
|[]->[x]
|y::ys->如果x []
|x::xs->插入x(排序xs)

人们总是在问这样的问题时,很难阅读这样的代码,而且大多数情况下他们会忽略帖子。 就像@Thomash所说的,首先尝试划分成更小的函数,这样就更容易看到它在哪里失败

您可以通过以下方式“用眼睛调试”:


你的建议很好。非常感谢Jeffrey.List.fold_left也可以用来代替List.fold_right,您只需更改
insert
insert\u sort
let rec insertion_sort el = function  
    | [] -> [el]
    | h::t as ls -> if el > h then h :: insert el t else (el :: ls) 

let sorted_list ls = List.fold_right insertion_sort ls []