双链表插入前端方法

时间:2014-02-26 22:10:28

标签: java

完成了我的命令,我弄错了。我不懂为什么。

对于我的插入前端,我执行以下操作。

head.next.prev = newNode; 
newNode.next = head;
newNode.prev = null;
head.prev = newnode;
head.next.prev = head; 
size++;

但相反,解决方案如下所示

head.next.prev = newNode(item, head, head.next); // newNode(item,prev,next); So basically head.next.prev is pointing to a newnode here newnode.prev = head and newnode.next = head.next. Ok that make sense. 
head.next = head.next.prev; // huh?
size++;
对我来说,解决方案没有意义,我的解决方案完全符合逻辑。如果你使head.next.prev =一个新节点,你应该使head.next.prev = head,否则会有一个跳跃对吗?也是head.next = head.next.prev;没有任何意义。该行基本上是说head.prev指向头部本身。不应该是head.next.prev = head;?

有谁可以指出发生了什么?我知道解决方案之间的格式不同,但我对逻辑更感兴趣

完整的代码如下所示

有很多困惑。所以这是声明头部的方式

 public class DList {

/**
 *  head references the sentinel node.
 *  size is the number of items in the list.  (The sentinel node does not
 *       store an item.)
 *
 *  DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS.
 */

protected DListNode head;
protected int size;

/* DList invariants:
 *  1)  head != null.
 *  2)  For any DListNode x in a DList, x.next != null.
 *  3)  For any DListNode x in a DList, x.prev != null.
 *  4)  For any DListNode x in a DList, if x.next == y, then y.prev == x.
 *  5)  For any DListNode x in a DList, if x.prev == y, then y.next == x.
 *  6)  size is the number of DListNodes, NOT COUNTING the sentinel,
 *      that can be accessed from the sentinel (head) by a sequence of
 *      "next" references.
 */

/**
 *  newNode() calls the DListNode constructor.  Use this class to allocate
 *  new DListNodes rather than calling the DListNode constructor directly.
 *  That way, only this method needs to be overridden if a subclass of DList
 *  wants to use a different kind of node.
 *  @param item the item to store in the node.
 *  @param prev the node previous to this node.
 *  @param next the node following this node.
 */
protected DListNode newNode(Object item, DListNode prev, DListNode next) {
return new DListNode(item, prev, next);
}

/**
 *  DList() constructor for an empty DList.
 */
public DList() {
head = newNode(null, head, head);
head.next = head;
head.prev = head;
size = 0;
}



    public insertfront(Object item){
???????????}
下面是DlistNoe.java

  public class DListNode {

  /**
   *  item references the item stored in the current node.
   *  prev references the previous node in the DList.
   *  next references the next node in the DList.
   *
   *  DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS.
   */

  public Object item;
  protected DListNode prev;
  protected DListNode next;

  /**
   *  DListNode() constructor.
   *  @param i the item to store in the node.
   *  @param p the node previous to this node.
   *  @param n the node following this node.
   */
  DListNode(Object i, DListNode p, DListNode n) {
    item = i;
    prev = p;
    next = n;
  }
}

2 个答案:

答案 0 :(得分:2)

您的插入代码有很多问题。请用英文阅读:

head.next.prev = newNode; 

将第一个节点的“prev”指向新节点(ok)

newNode.next = head;

将新节点的“下一个”指向头部(什么?)

newNode.prev = null;

将新节点的“prev”指向null(它是第一个节点,因此它应指向head)

head.prev = newnode;

将头部的“prev”指向null(你在前面插入所以你不应该触摸它)

head.next.prev = head; 

将第一个节点的prev指向head(撤消在第一步中执行的操作)

所以现在你的头部仍然指向旧的第一个元素,并且不再指向列表的最后一个元素。还有一个未完全插入的新元素(它的“prev”不是指向任何东西,而它的“next”指向错误的元素)。

是的,不是真的正确,我会说。如果您阅读上述正确的解决方案,希望您会发现它更有意义。

答案 1 :(得分:1)

链接列表等结构的问题在于,当您开始修改引用时,会丢失哪个节点。

所以,让我们命名一些节点。

插入前的链接列表:

H -> A -> B -> C
H.next = A
H.prev = null
A.next = B
A.prev = H
And so on...

目标链接列表:

H -> N -> A -> B -> C
H.next = N
H.prev = null (unchanged)
A.next = B (unchanged)
A.prev = N
N.next = A
N.prev = H

基于DList不变量和给定的解决方案,有一个头节点没有保持值的头部。

然后让我们逐步完成您的代码:

head.next.prev = newNode; // H.next -> A, A.prev = N. This seems fine.
newNode.next = head;      // N.next = H. What? This doesn't match our goal.
newNode.prev = null;      // N.prev = null. Also doesn't match our goal.
head.prev = newnode;      // H.prev = n. Also doesn't match our goal.
head.next.prev = head;    // H.next -> A, looks like you mean this to be N, but its still A.
                          // thus A.prev = H. Also doesn't match our goal.
size++;

最后,让我们看看给定的解决方案。

head.next.prev = newNode(item, head, head.next);
// First the function, H.next -> A, so...
// N.prev = H. Matches goal.
// N.next = A. Also matches goal.
// Then the assignment:
// head.next -> A, A.prev = N. Matches goal.    
head.next = head.next.prev;
// head.next -> A, A.prev -> N, H.next = N. Matches goal.
size++;

因此,所有4个已更改的引用都已设置。