输入:未排序列表/输出:排序列表
我的基本想法是在排序列表中插入一个整数。
(如果我可以将第一个元素插入到排序的尾部,我可以对列表进行排序。)
我使用了“insert”,这是帮助函数。
然而,它会溢出。 Couuld有人告诉我这是什么问题吗?
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)) ;;
答案 0 :(得分:6)
再次,我有风格建议:
sort
和insert
分开,因为它会使它更具可读性,并且因为insert
函数本身也很有用。insert
函数的参数?在OCaml中,人们会使用currying并写insert x l
而不是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)
答案 1 :(得分:4)
这条线对我来说看起来很不对:
| y1::y2::ys-> if y1<y2 then n::dest else y2::insert(y1,xs)
在我看来,你知道你的ys
已被排序(通过归纳假设)。因此,您应该将n
与ys
进行比较,而不是将ys
与对方进行比较。如果你把这条线弄平了,事情可能会有所改善。
对于它的价值,我怀疑你只需要在match
中有两个案例。我不明白为什么你需要以不同于任何其他非空列表的方式处理1元素列表。
答案 2 :(得分:2)
总是在提出这样的问题时,人们很难阅读这些代码,而且大多数人都会忽略这些代码。 就像@Thomash所说的那样,首先尝试分成更小的功能,这样就更容易看出它失败的地方。
你可以“用眼睛调试”这个:
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 []