【问题标题】:Doubly linked list java method for inserting at the beginning用于开头插入的双向链表java方法
【发布时间】:2021-01-20 17:44:42
【问题描述】:

我在网上找到了这段代码,并试图了解它是如何工作的。

public void insertFirst( int e )
   {if(isEmpty())
        {
            head = trail = new DNode(e, null, null); //(data, prev, next)
        }
        else {
            head.prev = new DNode(e, null, head);
            head = head.prev;
        }
        
        size++;
}

在代码的第一部分,

if(isEmpty())
            {
                head = trail = new DNode(e, null, null); //(data, prev, next)
            }

这意味着如果双向链表为空,则创建连接到prev null 和next null 的Node。然后将其设置为头和尾。

然后代码的第二部分是,

else {
                head.prev = new DNode(e, null, head);
                head = head.prev;
            }

我真的不明白这在 else 语句中是如何工作的。

你能解释一下吗?

谢谢

【问题讨论】:

  • 抱歉,这不是 Stack Overflow 的工作方式。这不是一个论坛或教程网站。请访问help center,接听tour 并阅读How to Ask
  • 哦,对不起。我只是stackoverflow的新手。谢谢你告诉我。

标签: java linked-list


【解决方案1】:

如果列表为空,您只需创建一个节点,该节点没有 `prev` 和 `next` 元素。

如果列表不为空:
null <- [head] -> [node] ...

这是一个非空头节点的结构。 如果你插入一个新的head,算法是:

  1. [new_head] &lt;- [head]// head.prev = new DNode(e, null, head); 在 DNode 的构造函数中null 意味着new_head 没有prev 元素。 而head 表示new_head 的下一个元素是head

  2. 但您尚未更改 head 引用。因此,您将新的头部引用 (= new_head) 设置为 head = head.prev;,因为 head.prev == new_head

【讨论】:

  • 如果列表为空,那么我将创建一个没有“prev”和“next”的节点。这是否意味着该节点也将是头和尾?
  • 如果列表为空,那么我将创建一个没有“prev”和“next”的节点。但是随后,新创建的节点将不会连接到头部和尾部。我觉得我需要一些东西来将新节点连接到 head.setNext(newNode) 和 tail.setPrev(newNode)。不是吗?
  • " 这是否意味着该节点也将是头和尾?" - 是的,你是对的。如果列表为空,则表示:Node head = nullNode tail == null。当您将新节点添加到列表中时,您将拥有head == tail。此外,这个新节点不会有任何prevnext 元素。 null &lt;- head/tail -&gt; null(在单节点情况下)。
【解决方案2】:

我会稍微分解一下并注释代码来解释它:

public void insertFirst(int e){
    if(isEmpty()) {
        // null <-prev-- [newHead(e)] --next-> null
        DNode newHead =  new DNode(e, null, null);

        // list.head --> [newHead(e)] <-- list.trail
        head = newHead;
        trail = newHead;

    } else {
        // null <-prev-- [newHead(e)] --next-> [head(other_e)] . . .
        DNode newHead =  new DNode(e, null, head);

        // [newHead(e)] <-prev-- [head(other_e)] . . .
        head.prev = newHead;

        // list.head --> [newHead(e)] . . .
        head = head.prev; // since 'head.prev' holds 'newHead'
       
        // now you have this:
        // list.head -> [newHead(e)] --next-> [oldHead(other_e)] --next-> (.. maybe others ..) <-- list.trail
        //              [          ] <-prev-- [                ]
    }
    size++;
}

【讨论】:

  • 那么,oldHead 将包含元素,newHead 将成为虚拟节点?
  • @bdd0 不,newHead 包含 e 您要放入列表的元素。 list.head指向newHead作为第一个节点,newHead.next指向oldHead作为第二个节点,oldHead.next仍然指向它之后的元素,等等。所有节点仍然保留元素他们正在举行。我已将 cmets 更新为更直观
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-18
  • 2017-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多