完成了我的命令,我弄错了。我不懂为什么。
对于我的插入前端,我执行以下操作。
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;
}
}
答案 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个已更改的引用都已设置。