Java 反向列表实现和指针理解
假设我有一个名为Node的类:Java 反向列表实现和指针理解,java,pointers,nodes,Java,Pointers,Nodes,假设我有一个名为Node的类: public class Node { public Node next; //etc...... } 和类节点列表: public class NodesList { public Node head; //etc.... } 现在我想实现一个函数来反转列表,如下所示: public reverseList () { Node curr = head; Node prev = null;
public class Node {
public Node next;
//etc......
}
和类节点列表:
public class NodesList {
public Node head;
//etc....
}
现在我想实现一个函数来反转列表,如下所示:
public reverseList () {
Node curr = head;
Node prev = null;
while (curr != null){
curr.next = prev;
prev = curr;
head = head.next;
curr = head;
}
head = prev;
}
我的问题很基本:我分配了curr=head
为什么,在作业curr.next=prev中,不会将标题也更改为head.next=prev并破坏列表
我在哪里可以读到更多关于它的信息来了解幕后发生的事情
非常感谢
为什么,在作业curr.next=prev
中,它不会将head
也更改为head.next=prev
,并破坏列表
但是它确实改变了head.next
到prev
。在该赋值点,curr
和head
是对同一对象的引用。这不会破坏列表,因为在循环中运行时,head
会被设置为其他元素
如果这听起来有点混乱,请继续阅读
我在哪里可以读到更多关于它的信息来了解幕后发生的事情
幕后没有任何事情,你只需要对“幕后”发生的事情有一个正确的看法
发生的情况是,您正在使用旧列表的相同节点构建一个反向列表。现在,您正在以唯一的方式遍历旧列表,这是向前的—从旧列表的头部到尾部,通过.next
前进。但对于新列表,这需要是列表的结尾,因此每当您看到另一个元素时,您都会将其添加到正在构建的列表的开头之前,而不是后面
如果你有:
(head) -> [node 1] -> [node 2] -> [node 3]
您正在将其转换为:
null <- [node 1] <- (head) [node 2] -> [node 3] -> null
null <- [node 1] <- [node 2] <- (head) [node 3] -> null
null <- [node 1] <- [node 2] <- [node 3] <- (head)
null
无效的
为什么,在作业curr.next=prev
中,它不会将head
也更改为head.next=prev
,并破坏列表
但是它确实改变了head.next
到prev
。在该赋值点,curr
和head
是对同一对象的引用。这不会破坏列表,因为在循环中运行时,head
会被设置为其他元素
如果这听起来有点混乱,请继续阅读
我在哪里可以读到更多关于它的信息来了解幕后发生的事情
幕后没有任何事情,你只需要对“幕后”发生的事情有一个正确的看法
发生的情况是,您正在使用旧列表的相同节点构建一个反向列表。现在,您正在以唯一的方式遍历旧列表,这是向前的—从旧列表的头部到尾部,通过.next
前进。但对于新列表,这需要是列表的结尾,因此每当您看到另一个元素时,您都会将其添加到正在构建的列表的开头之前,而不是后面
如果你有:
(head) -> [node 1] -> [node 2] -> [node 3]
您正在将其转换为:
null <- [node 1] <- (head) [node 2] -> [node 3] -> null
null <- [node 1] <- [node 2] <- (head) [node 3] -> null
null <- [node 1] <- [node 2] <- [node 3] <- (head)
null
nullcurr
和head
最初指向第一个节点。如果执行curr.next=prev
,则curr.next
和head.next
均为null
。由于第一个节点与列表其余部分之间的连接丢失,您现在无法反转列表。现在,当执行head=head.next
语句时,您的head
将指向null
,这意味着列表没有起点
要记住的一件事是,永远不要使用head
指针在列表中的节点之间移动<代码>标题应始终指向列表的开头。在反转列表的情况下,head
可以更新为在反转后指向列表的新开始节点
撤销列表的一种方法是:
Node prev = null;
Node curr = head;
Node next;
while (curr != NULL)
{
next = curr.next;
curr.next = prev;
prev = current;
current = next;
}
head = prev;
在上面的代码片段中,有一个名为next
的指针,它将首先指向current
的下一个节点。因此,现在在执行curr.next=prev
之后,curr可以通过语句curr=next
移动到列表中要反转的下一个节点。这样可以确保列表的连接不会丢失
while循环反转列表后,prev
将指向列表的新的第一个节点。现在,您可以修改头部
以指向此节点。curr
和头部
最初指向第一个节点。如果执行curr.next=prev
,则curr.next
和head.next
均为null
。由于第一个节点与列表其余部分之间的连接丢失,您现在无法反转列表。现在,当执行head=head.next
语句时,您的head
将指向null
,这意味着列表没有起点
要记住的一件事是,永远不要使用head
指针在列表中的节点之间移动<代码>标题应始终指向列表的开头。在反转列表的情况下,head
可以更新为在反转后指向列表的新开始节点
撤销列表的一种方法是:
Node prev = null;
Node curr = head;
Node next;
while (curr != NULL)
{
next = curr.next;
curr.next = prev;
prev = current;
current = next;
}
head = prev;
在上面的代码片段中,有一个名为next
的指针,它将首先指向current
的下一个节点。因此,现在在执行curr.next=prev
之后,curr可以通过语句curr=next
移动到列表中要反转的下一个节点。这样可以确保列表的连接不会丢失
while循环反转列表后,prev
将指向列表的新的第一个节点。现在,您可以修改头部
以指向此节点。而不是推理什么指向什么,更简单的是推理pop和push操作。在伪代码中,您可以将lst
反转到rvs
上,如