当我们将一个节点插入到链表的头部时,我们可以使用以下代码:
Node oldfirst = first;
first = new Node();
first.item = "not";
first.next = oldfirst;
,Node的定义如下,
private class Node
{
Item item;
Node next;
}
我的问题是,因为在java中,对象变量是引用,所以oldfirst和first应始终指向同一个节点。如果这是真的,则无法将节点插入头部。我哪里错了?
我还在解决问题“合并两个排序列表”中找到了这样的代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode p1 = l1;
ListNode p2 = l2;
ListNode fakeHead = new ListNode(0);
ListNode p = fakeHead;
while(p1 != null && p2 != null){
if(p1.val <= p2.val){
p.next = p1;
p1 = p1.next;
}else{
p.next = p2;
p2 = p2.next;
}
p = p.next;
}
if(p1 != null)
p.next = p1;
if(p2 != null)
p.next = p2;
return fakeHead.next;
}
}
在上面的代码中,p是dummyHead的引用,所以当它返回时,p已被更改,dummyHead.nex仍然是合并列表的头部吗?
谢谢!
答案 0 :(得分:1)
这将解释:
Node oldfirst = first; // oldFirst points to the same node as first
first = new Node(); // first now points to a new node.
// oldFirst stays pointing to the original first node
first.item = "not"; // update the item of the new first node
first.next = oldFirst; // .next of the new node points to the old original first node
因此,此代码在列表的开头插入一个新节点。
答案 1 :(得分:0)
引用本身就是变量,它们只是指向内存中的地址。
在您的情况下, oldFirst 和 first 是指向同一对象的不同引用,这就是为什么当您将第一个设置为指向其他东西, oldFirst 不受影响,因为它是一个不同的参考,实际上它是 第一个参考,但不是相同的参考。
如果你仍然不明白'int'数据类型,你可以得到int a = 10;和int b = 10;两个int都指向同一个整数,当你设置a等于12时,b不受影响,引用的工作方式相同。
在C#中,您可以通过引用和值将引用传递给函数(您不能通过java中的引用传递)。所以如果你有一个功能:
void Foo(ref SomeType x); // pass by reference
在函数 Foo 的范围内,你将获得与传递给这个函数相同的东西,所以如果你重置x指向别的东西,你将改变你传递给这个函数的东西
但是如果你写了这个:
void Foo(SomeType x);
然后x将按值传递,这意味着x将是您传递给函数 Foo 的引用的副本,如果您将其重置为指向其他内容,则不会影响您传入该函数的引用。