当前位置: 首页 > 知识库问答 >
问题:

从双链表中删除中间节点

诸葛卜霸
2023-03-14

我试图从基于阉羊的双链表中删除一个元素,该列表中的节点满足返回bool的函数。由于某种原因,替换节点的前一个指针(下一个被删除)不更新,而是引用回它自己。

我的代码

(* The type of linked lists. *)
type 'a llist =
  | Nil
  | Cons of (float * 'a) * 'a lcell * 'a lcell
and 'a lcell = ('a llist) ref

let remove p head =
  let rec remove' ll =
    match !ll with
    |Nil -> head := !head (*no node match*)
    |Cons ((a, _), c, d) -> 
        if p a then
          match (!c, !d) with
          |(Nil, Nil) -> head := ref Nil (*singleton match*)
          |(Cons(_, c', d'), Nil) -> (*last node match*)
              d' := Nil 
          |(Nil, Cons(_, c', d')) -> (*first node match*)
              head := d;
              c':= Nil
          |(Cons(_, _, d'), Cons(_, e', _))-> (*middle match; Does not work*)
              e' := !c;
              d' := !d
        else
          remove' d
  in
  remove' !head

测试结果

Initial value of head is
{contents =
 @1:{contents =
     Cons ((-1.689, 3),
           @2:{contents = Nil},
           @3:{contents =
               Cons ((0.910, -1),
                     <@1>,
                     @4:{contents =
                         Cons ((0.647, 3),
                               <@3>,
                               @5:{contents =
                                   Cons ((4.531, -1),
                                         <@4>,
                                         @6:{contents = Nil})})})})}}

Calling remove (fun x -> close x 0.646639313413) head (*close compares values accuracy up to two decimal digits*)

The value of head is now
{contents =
 @1:{contents =
     Cons ((-1.689, 3),
           @2:{contents = Nil},
           @3:{contents =
               Cons ((0.910, -1),
                     <@1>,
                     @4:{contents =
                         Cons ((4.531, -1), <@4>, @5:{contents = Nil})})})}}

共有1个答案

都才俊
2023-03-14

所以,现在发生的是:

我们有内存块M1, M2, M3:

>

M2包含对象Cons((v2, x2), M1, M3)=Cons(_, c, d);

M3包含对象Cons((v3,x3),M2,r3)=Cons(u,e',u);

然后,当我们做e':=!Cd':=!d,我们正在做的是:

>

*M2=*M3:以M3为单位复制对象,并以M2为单位存储;

因此,我们得到的结果是:

>

  • M1包含对象Cons((v1,x1),l1,M2);

    M2包含对象Cons((v3,x3),M2,r3);

    M3包含对象Cons((v3,x3),M2,r3);

    这是我们在html" target="_blank">测试中看到的结果。

    要正确更改链表,我们可以在M2中创建一个新对象,该对象的值存储在M3中,但使用更新的左指针(另一个选项是在M1和M3中创建新对象)。

    这就是我要做的:

    let remove p head =
      let aux node_ref =
      match !node_ref with
      | Nil -> ()
      | Cons((k, _), l, r) ->
        if p k then
          node_ref := (
            match !r with
            | Nil -> Nil
            | Cons((nk, nx), nl, nr) -> Cons((nk, nx), l, nr)
          )
        else
          aux r
      in
      aux head
    

  •  类似资料:
    • 我理解得对吗?(从虚拟节点开始) dummy->a->b->c->d->dummy(环绕到dummy节点) 因此,如果我想删除第一个实际的数据段(A),我需要将它分配给一个临时变量。所以Node first=head.next。然后我需要有一个虚拟的头部引用“B”,所以我需要做head.next=first.next。这就是所有需要做的吗? 在从列表中删除任何节点N的情况下(假设它在列表中),这是

    • 我有一个单链表。如果我想从这个链表中删除一个已知的元素,我能做什么? 例如:节点*头;(44)节点*尾部;(39) 链接列表:44 27 59 13 45 39我们想从中删除45。得到:4427591339 我只知道从列表中删除第一个元素(如果元素(需要删除)是列表的第一个元素)。我得到了:头=头- 如何从列表中删除中间节点?

    • 这是我的remove函数,用于删除具有元素的节点。我得到了一个seg错误,我很确定这是因为temp->prev是前面的哨兵,所以从技术上来说,它不在双链表中。如果这是正确的,我实际上如何防止这种情况?如有任何帮助,不胜感激。 编辑:刚刚更新了代码,但仍然出现了Seg错误

    • 双链表节点是在main函数中创建的。Ender和header已定义。在删除节点函数处中断-ender为空。 释放最后一个和第一个输入的内存的最佳方法是什么,即:删除:233,A和888,F?

    • 我有麻烦删除双向链表中的节点,程序崩溃,我不能解决这个问题。你能帮我吗?这是创建新节点,查看它们并删除它们的完整代码。 我认为这个问题与Node del的scanf()有关,但我不确定。当我只是通过或

    • 问题内容: 这段代码是一个表,可以选择“惰性名称”,“删除”,“显示”和“退出”。 该代码运行良好,但是我唯一的问题是如何删除节点中的所选名称 *我不知道如何删除节点。我应该在删除方法上加上什么? 问题答案: 要删除Node,您实际上需要更新它的上一个节点的位置以删除Node的位置,而剩下的Node最终将被垃圾回收。 如果要删除的节点是根节点,则只有一个问题,然后更新根节点。