当我们在链表的头部插入一个节点时,我们可以使用以下代码:
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。next仍然是合并列表的头吗?
谢谢!
这将解释:
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
所以这段代码在列表的开头插入一个新节点
引用本身就是变量,它们只是指向内存中的地址。
在你的例子中,oldFirst和first是指向同一个对象的不同引用,这就是为什么当你设置first指向别的东西时,oldFirst不受影响,因为它是一个不同的引用,实际上它是引用的副本,但不是同一个引用。
如果你仍然不明白,看看'int'数据类型,你可以用int a = 10;int b = 10;两个整型"指向"相同的整数,当你设置a等于12时,b不受影响,引用的工作方式相同。
在c#中,你可以按引用和按值传递引用到函数中(在java中不能按引用传递)。如果你有一个函数:void Foo(ref SomeType x); // pass by reference
在函数Foo的作用域中,您将拥有与传递给该函数相同的内容,因此如果您将x重置为指向其他内容,则将更改传递给该函数的内容。
但是如果你这样写:
void Foo(SomeType x);
则x将按值传递,这意味着x将是传递给函数Foo的引用的副本,如果您将其重置为指向其他内容,则不会影响传递给该函数的引用。