Ocaml 将元素插入到已排序的链表中
我们必须实现insert函数,该函数可以将单元格插入到已排序的链表中。我的实现思想是有两个rlist,称为previous和current,用于遍历列表。在函数调用开始时,前一个rlist将包含一个随机整数,其下一个字段指向当前单元格,该单元格是链接列表的头。我认为这是有问题的。我完成了我的想法。我认为该方法将在链表的正确位置添加正确的整数。但是,如果插入的元素位于列表的开头,则当使用“在屏幕上显示”时,列表仍然是旧列表,但旧列表确实有一个指向它的单元格,并且该单元格具有插入的整数。所以我不知道该怎么处理。 我测试了我的方法,但它并不像我描述的那样有效。 下面是我所做的:我在c3的末尾插入了-9。c3确实在列表的末尾得到了-9。然后我在c5里面加了4。但是c5现在变成了[5;4;-9]。所以它是错误的,它应该改为[5;4;3;2;1;-9]。所以我不知道怎么了 我在网上查阅了如何实现该方法,以便他们能给我一些启发或提示,但他们提供的解决方案通常是Java或其他编程语言Ocaml 将元素插入到已排序的链表中,ocaml,Ocaml,我们必须实现insert函数,该函数可以将单元格插入到已排序的链表中。我的实现思想是有两个rlist,称为previous和current,用于遍历列表。在函数调用开始时,前一个rlist将包含一个随机整数,其下一个字段指向当前单元格,该单元格是链接列表的头。我认为这是有问题的。我完成了我的想法。我认为该方法将在链表的正确位置添加正确的整数。但是,如果插入的元素位于列表的开头,则当使用“在屏幕上显示”时,列表仍然是旧列表,但旧列表确实有一个指向它的单元格,并且该单元格具有插入的整数。所以我不知道
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
部分没有用括号括起来,这似乎很奇怪。如果你能给出一个代码失败的例子,而不是它应该如何工作的例子,那会更有帮助。