我正在学习链接的数据结构,这个概念对我来说是有意义的,但是代码没有意义。
我希望有人能为我解释这件事。
这是来自演讲幻灯片:
我这里有一个构造函数:
private static class Node<E> {
private E value;
private Node<E> next;
private Node( E value, Node<E> next ) {
this.value = value;
this.next = next;
}
}价值-存储实际信息。下一个-存储对先前存储的对象的引用。合乎道理。
但后来..。
public void addFirst( E o ) {
Node<E> newNode = new Node<E>( o, null );
if ( head == null ) {
head = newNode;
} else {
newNode.next = head;
head = newNode;
}
}上面的代码应该是添加元素。
但我的问题是:newNode创建了。newNode.next字段存储对对象头的引用。(顺便说一下,我不知道head是在哪里声明的),然后是:head=newNode。
那么Head现在有了newNode存储的值,而head.next现在正在引用自己?
这里的问题是,head中的原始值丢失了,并且没有引用newNode。
我是不是遗漏了什么?
发布于 2014-04-02 21:22:44
我觉得你错过了物体的身份。考虑以下类及其字段:
List<E>
Node<E> head
Node<E>
E value
Node<E> next假设您有一个空列表,这意味着有这些对象(实际上只有一个):
List(1)
head = null为了更好地说明,我给了这个对象一个唯一的数字。在现实中,对象明确地通过其内存位置来识别。
现在将"as"添加到列表中:
Node<E> newNode = new Node<E>( o, null );
List(1)
head = null
Node(2)
value = "as"
next = nullhead = newNode;
List(1)
head = Node(2)
Node(2)
value = "as"
next = null现在添加"df"
Node<E> newNode = new Node<E>( o, null );
List(1)
head = Node(2)
Node(2)
value = "as"
next = null
Node(3)
value = "df"
next = nullnewNode.next = head;
List(1)
head = Node(2)
Node(2)
value = "as"
next = null
Node(3)
value = "df"
next = Node(2)head = newNode;
List(1)
head = Node(3)
Node(2)
value = "as"
next = null
Node(3)
value = "df"
next = Node(2)如您所见,单个节点的值没有被更改,而新的head、Node(3)不引用自己。head有值"df",下一个节点有"as",因此"df"确实是在现有节点前面添加的。
正如其他人所指出的,addFirst可以大大简化。看原稿:
Node<E> newNode = new Node<E>( o, null );
if ( head == null ) {
head = newNode;
} else {
newNode.next = head;
head = newNode;
}head = newNode;行出现在两个if分支的底部,因此可以将其移出:
Node<E> newNode = new Node<E>( o, null );
if ( head == null ) {
} else {
newNode.next = head;
}
head = newNode;...which将then分支保持为空,因此最好逆转这种情况:
Node<E> newNode = new Node<E>( o, null );
if ( head != null ) {
newNode.next = head;
}
head = newNode;仔细观察,在那个if之后,newNode.next将是(旧的) head,而不管if是否被执行(那么很明显)(构造函数将它设置为null,如果if没有执行,那么head也是null )。所以另一种写这个的方法是:
Node<E> newNode = new Node<E>( o, head );
head = newNode;现在您有了一个只使用过一次的变量:
head = new Node<E>( o, head );但实际上,以更好的理解方式编写代码,尤其是如果您的目标是学习的话。
发布于 2014-04-02 21:04:18
将addFirst简化为:
public void addFirst( E o ) {
head = new Node<E>( o, head );
}head将被设置为新节点。老脑袋将在head.next。
发布于 2014-04-02 21:04:20
是的,您忽略了名为addFirst的方法,因此它是在头之前添加元素的方法。这正是方法真正要做的。它创建一个新节点,将其设置为头上的下一个节点,然后更新列表的头,指向新创建的节点。
由于java是按值传递的,所以这段代码应该正确工作。
https://stackoverflow.com/questions/22822894
复制相似问题