简体   繁体   English

为什么对象的值会改变,即使它有不同的引用?

[英]Why object's value changes even though it has different references?

I am confused about objects references here.我对这里的对象引用感到困惑。 It is LC problem to merge 2 sorted linked lists.合并 2 个已排序的链表是 LC 问题。

I understand that at first iteration current.next and result have reference the same object so when i assign new value to current.next the result value changes as well.我知道在第一次迭代current.nextresult引用了同一个对象,所以当我为current.next分配新值时, result值也会改变。

At the second iteration both r1 and r2 are false so result, current and current.next point to diffrent objects.在第二次迭代时,r1 和 r2 都是假的,因此result, current and current.next指向不同的对象。

What i don't understand is why assigning new value to current ( current = current.next ) doesn't modify result object but current.next = l1/l2 does?我不明白的是为什么将新值分配给 current ( current = current.next ) 不会修改结果对象但current.next = l1/l2会?

Could someone explain it to me please?有人可以向我解释一下吗?

public static ListNode MergeTwoLists(ListNode l1, ListNode l2)
        {
            if (l1 == null) return l2;
            if (l2 == null) return l1;
            if (l2 == null && l1 == null) return null;

            ListNode result = new ListNode(0);
            ListNode current = result;

            while (l1 != null && l2 != null)
            {
                var r1 = Object.ReferenceEquals(result, current);
                var r2 = Object.ReferenceEquals(result, current.next);
                
                if (l1.val < l2.val)
                {
                    current.next = l1;
                    l1 = l1.next;
                }
                else
                {
                    current.next = l2;
                    l2 = l2.next;
                }

                current = current.next;
            }

            // l1 is lognger than l2 
            if(l1 != null)
            {
                current.next = l1;
                l1 = l1.next;
            }

            // l2 is lognger than l1 
            if (l2 != null)
            {
                current.next = l2;
                l2 = l2.next;
            }

            return result.next;
        }
public class ListNode
    {
        public int val;
        public ListNode next;
        public ListNode(int x = 0, ListNode next = null)
        {
            val = x;
            next = null;
        }
    }

EDIT编辑

Let's say we have these:假设我们有这些:

Input: l1 = [1,2,4], l2 = [1,3,4]    Output: [1,1,2,3,4,4] 

1st iteration :第一次迭代:

r1 = true , both result and current point to the same object. r1 = true , result 和 current 都指向同一个对象。

r2 = false

l1.val == l2.val so we execute l1.val == l2.val所以我们执行

else
{
  current.next = l2;
  l2 = l2.next;
}

At this moment we have: result = [0,1,3,4] , current = [0,1,3,4], l2 = [3,4]此时我们有: result = [0,1,3,4] , current = [0,1,3,4], l2 = [3,4]

Next we execute current = current.next , so current = [1,3,4] and it doesn't point to result anymore.接下来我们执行current = current.next ,所以current = [1,3,4]并且它不再指向 result 。

2nd iteration第二次迭代

r1 = false , both result and current point to the different object. r1 = false , result 和 current 都指向不同的对象。

r2 = false , r2 = false

l1.val < l2.val so we execute l1.val < l2.val所以我们执行

if (l1.val < l2.val)
{
    current.next = l1;
    l1 = l1.next;
}

At this moment we have:此刻我们有:

result = [0,1,1,2,4], current = [1,1,2,4], l2 = [3,4], l1 = [2,4]

Here is the part i don't understand : Result and current point to diffrent objects, still when current changes result does as well.这是我不明白的部分:结果和当前指向不同的对象,当当前更改结果时仍然如此。 How result keeps reference to current??结果如何保持对当前的引用?

Next we execute current = current.next , so current = [1,2,4] , so we modify current but this time result doesn't change.接下来我们执行current = current.next ,所以current = [1,2,4] ,所以我们修改 current 但这次结果没有改变。

Result and current point to diffrent objects, still when current changes result does as well.结果和当前指向不同的对象,当当前更改结果时仍然如此。 How result keeps reference to current?结果如何保持对当前的引用?

Look at this part of your question:看看你问题的这一部分:

so current = [1,3,4] and it doesn't point to result anymore.所以current = [1,3,4]它不再指向结果。

Importantly, the 1 in that list is the same element as the 1 in result = [0,1,3,4] .重要的是, 1在该列表作为相同的元件1result = [0,1,3,4] If you modify the next field of that 1 node, you will modify any list that node is a member of.如果您修改该1节点的next字段,您将修改该节点所属的任何列表。 Including the list that result is referencing.包括result引用的列表。

Later when you write:后来当你写:

At this moment we have:此刻我们有:

result = [0,1,1,2,4], current = [1,1,2,4], l2 = [3,4], l1 = [2,4]

Note that the list result points to is not the same as the list current points to.请注意,该列表result点是一样的列表current点。 But after that first node, it is the same.但是在第一个节点之后,它相同的。

After the first iteration, result.next references the same object that current does.在第一次迭代之后, result.next引用与current相同的对象。 This is because result and current started at referencing the same object, and then as the last step of the first iteration, current was changed to reference current.next .这是因为resultcurrent从引用同一个对象开始,然后作为第一次迭代的最后一步, current更改为引用current.next Since current and result were at that point the same, current.next and result.next are also the same.由于currentresult在这一点上相同,因此current.nextresult.next也相同。 So after changing current to current.next , that's the same as setting it to result.next .因此,将current更改为current.next ,这与将其设置为result.next相同。

So on the second iteration, result.next and current are the same.所以在第二次迭代中, result.nextcurrent是一样的。 This means that when you modify current.next , that's the same as modifying result.next.next , which has the effect of replacing the contents of the result list beyond the first two elements, with the new chain of elements that l2 referenced.这意味着,当您修改current.next ,这与修改result.next.next相同,这具有将result列表中除前两个元素之外的内容替换为l2引用的新元素链的效果。

Again: the key here is that each variable simply points to a single node.再说一遍:这里的关键是每个变量都指向一个节点。 It's fine to conceptualize that as pointing to a list of nodes, but only if you remember that if you modify the next field of any node in that list, you are modifying the entire list, even if the variable is not referencing the variable that references the root of the list.可以将其概念化为指向节点列表,但前提是您记住,如果您修改该列表中任何节点的next字段,则您正在修改整个列表,即使该变量未引用引用的变量列表的根。

You should never assign current.next to nodes from l1 or l2 .您永远不应该将current.next分配给来自l1l2节点。 Instead you must create a new ListNode that has the same value as l1 or l2 and make current.next point to your new ListNode .相反,你必须创建一个新ListNode具有相同的值l1l2current.next点到新ListNode Otherwise you're trying to straighten a bowl of spaghetti, which is an impossible task.否则你会试图把一碗意大利面弄直,这是一项不可能完成的任务。 You need to build your own new strand of spaghetti.你需要建立自己的新意大利面条链。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将对象从Main()传递给函数会更改对象,即使C#是按值进行的? - Passing object from Main() to function changes the object , even though C# is by value? 未选择数据绑定 Combobox 中的初始项目。 即使绑定的 Object 有一个值 - Initial Item in Data bound Combobox is not selected. Even though the Bound Object has a Value 即使值更改,列表也会保持相同的第一个值 - List keeps getting same first value, even though value changes 为什么字符串实习但有不同的引用? - Why string interned but has different references? 为什么我的 FindGameObjectByTag() 找到相同的对象两次,即使它被破坏了? - Why does my FindGameObjectByTag() find the same object twice even though it's destroyed? 注册表项的值即使有值也返回为null - Value of registry key is returned as null even though it has a value 即使对象已选择= true,我的MVC SelectList仍未选择? - My MVC SelectList not selecting even though object has selected = true? 为什么我的服务说它正在运行,即使它不是? - why does my service says it's running even though it's not? 为什么 MemoryStream() 有数据,即使它没有用任何数据源初始化 - Why MemoryStream() has data even though it is not initialized with any source of data 为什么我的变量类型为List <Point> 即使我没有使用引用也被更改了吗? - Why is my variable of type List<Point> being changed even though I'm not using references?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM