Ocaml 将元素插入到已排序的链表中

Ocaml 将元素插入到已排序的链表中,ocaml,Ocaml,我们必须实现insert函数,该函数可以将单元格插入到已排序的链表中。我的实现思想是有两个rlist,称为previous和current,用于遍历列表。在函数调用开始时,前一个rlist将包含一个随机整数,其下一个字段指向当前单元格,该单元格是链接列表的头。我认为这是有问题的。我完成了我的想法。我认为该方法将在链表的正确位置添加正确的整数。但是,如果插入的元素位于列表的开头,则当使用“在屏幕上显示”时,列表仍然是旧列表,但旧列表确实有一个指向它的单元格,并且该单元格具有插入的整数。所以我不知道

我们必须实现insert函数,该函数可以将单元格插入到已排序的链表中。我的实现思想是有两个rlist,称为previous和current,用于遍历列表。在函数调用开始时,前一个rlist将包含一个随机整数,其下一个字段指向当前单元格,该单元格是链接列表的头。我认为这是有问题的。我完成了我的想法。我认为该方法将在链表的正确位置添加正确的整数。但是,如果插入的元素位于列表的开头,则当使用“在屏幕上显示”时,列表仍然是旧列表,但旧列表确实有一个指向它的单元格,并且该单元格具有插入的整数。所以我不知道该怎么处理。 我测试了我的方法,但它并不像我描述的那样有效。 下面是我所做的:我在c3的末尾插入了-9。c3确实在列表的末尾得到了-9。然后我在c5里面加了4。但是c5现在变成了[5;4;-9]。所以它是错误的,它应该改为[5;4;3;2;1;-9]。所以我不知道怎么了

我在网上查阅了如何实现该方法,以便他们能给我一些启发或提示,但他们提供的解决方案通常是Java或其他编程语言

type cell = { data : int; next : rlist}
and rlist = cell option ref 

let c1 = {data = 1; next = ref None}
let c2 = {data = 2; next = ref (Some c1)}
let c3 = {data = 3; next = ref (Some c2)}
let c5 = {data = 5; next = ref (Some c3)} 

let rec displayList (c : rlist) =
  match !c with
  | None -> []
  | Some { data = d; next = l } -> d :: (displayList l) 

let cell2rlist (c : cell) :rlist = ref (Some c) 

let bigger((x:int), (y:int)) = (x > y) 



let insert (comp : (int * int) -> bool) (item : int) (listt :rlist)=
  let itemm = {data=item ; next = ref None} in
  let rec helper (prev : rlist) (item : cell) (current: rlist) funcc =
    match !current with
    |None -> (match !prev with 
        |Some w -> w.next := (Some itemm))
    |Some q -> if comp (item.data, q.data) then (itemm.next := (Some q) ; match !prev with 
      |Some w -> w.next := (Some itemm))
        else  prev := !current; current:= !(q.next); (helper prev item current funcc)
  in let previous = ref (Some {data=0; next = listt}) in
  helper previous itemm listt comp
下面是代码正确返回值的示例:

 let l5 = cell2rlist c5;;
val l5 : rlist = ....
(* Messy display deleted. *)



 displayList l5;;
- : int list = [5; 3; 2; 1]


 displayList l5;;
- : int list = [5; 3; 2; 1]


 insert bigger 4 l5;;
- : unit = ()


 displayList l5;;
- : int list = [5; 4; 3; 2; 1]


 insert bigger 9 l5;;
- : unit = ()


 displayList l5;;
- : int list = [9; 5; 4; 3; 2; 1]


 insert bigger 0 l5;;
- : unit = ()


 displayList l5;;
- : int list = [9; 5; 4; 3; 2; 1; 0]
但当我运行代码时,我得到的是:

insert bigger 10 (ref(Some c5)) ;;
- : unit = ()

c5 ;;
- : cell =
{data = 5;
 next =
  {contents =
    Some
     {data = 3;
      next =
       {contents =
         Some
          {data = 2;
           next = {contents = Some {data = 1; next = {contents = None}}}}}}}}
如你所见,如果我在列表的开头插入一个数字,我就看不到它了

再举一个例子,

insert bigger 4 (ref(Some c5)) ;;
- : unit = ()

c5 ;;
- : cell =
{data = 5;
 next =
  {contents =
    Some
     {data = 4;
      next = {contents = Some {data = 1; next = {contents = None}}}}}}
因此,正如您所看到的,代码根本不起作用,因为更新的列表应该有值
[5;4;3;2;1]
,但它有
[5;4;1]

下面是另一个例子:

insert bigger (-9) (ref(Some c3)) ;;
- : unit = ()

c3 ;;
- : cell =
{data = 3;
 next =
  {contents =
    Some
     {data = 2;
      next =
       {contents =
         Some
          {data = 1;
           next = {contents = Some {data = -9; next = {contents = None}}}}}}}}

因此,该方法似乎确实将元素正确地插入列表,但插入的单元格假定指向的列表似乎是错误的。

作为参考,下面是一个显示代码失败的会话:

# let (l: rlist) = ref None;;
val l : rlist = {contents = None}
# insert bigger 1 l;;
- : unit = ()
# l;;
- : rlist = {contents = Some {data = 1; next = {contents = None}}}
# insert bigger 0 l;;
- : unit = ()
# l;;
- : rlist = {contents = None}
值得一提的是,如果代码正确缩进也会很好

无论如何,当我在短时间内查看您的代码时,我看到的是以下片段:

current:= !(q.next);
helper prev item current funcc
在我看来,就像你想象的那样,这里的第一行将推进一些局部变量,以指向列表的下一个元素。但它实际上是在修改列表

您可能想要更像这样的东西:

helper prev item q.next funcc

代码中还有其他问题。例如,
then
部分用括号括起来,而
else
部分没有用括号括起来,这似乎很奇怪。

如果你能给出一个代码失败的例子,而不是它应该如何工作的例子,那会更有帮助。