java—这段代码是如何填充dummy和l3列表的?

zbdgwd5y  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(351)

在这段代码中,我使用了虚拟节点的概念。为此,我了解虚拟列表是如何填充的,但是,我似乎无法理解l3列表也是如何填充的。我只是把它看作是虚拟列表的初始值。
例如,当代码第一次运行时,考虑l1(1>2>4)和l2(1>3>4)。当dummy.next语句运行时,它同时填充dummy和l3。为什么?

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode l3 = new ListNode(0);
        ListNode dummy = l3;

        while(l1 != null && l2 != null){
            if(l1.val <= l2.val){
                dummy.next = l1;
                l1 = l1.next;
            }
            else{
                dummy.next = l2;
                l2 = l2.next;
            }

            dummy = dummy.next;
        }

        return l3.next;   
    }
ha5z0ras

ha5z0ras1#

让我们用一个例子来说明这个问题。假设我们有以下两个列表:

[L1-one | next] --> [L1-two | next] --> [L1-three | next] --> null
[L2-one | next] --> [L2-two | next] --> null

其中第一个“字段”反映了其他讨论和 --> 反映了 next -参考文献。
现在算法开始接收两个列表 l1 以及 l2 作为参数:

l1
   |
   v
[L1-one | next] --> [L1-two | next] --> [L1-three | next] --> null
[L2-one | next] --> [L2-two | next] --> null
   ^
   |
  l2

它为新列表创建一个虚拟节点,并将其存储为 l3 以及 dummy ```
l3, dummy
|
v
[L3-dummy | next] --> null

现在取决于 `l1.val < l2.val` ,或者 `l1` 或者 `l2` 将设置为 `dummy.next` . 让我们假设 `l1.val < l2.val` ,因此 `l1` 设置为 `dummy.next` :

l3, dummy
|
v
[L3-dummy | next] --.
|
l1 .-------------.
| |
v v
[L1-one | next] --> [L1-two | next] --> [L2-three | next] --> null

[L2-one | next] --> [L2-two | next] --> null
^
|
l2

接下来, `l1` 设置为 `l1.next` :

l3, dummy
|
v
[L3-dummy | next] --.
|
.-------------. l1
| |
v v
[L1-one | next] --> [L1-two | next] --> [L1-three | next] --> null

[L2-one | next] --> [L2-two | next] --> null
^
|
l2

最后,在最后一步, `dummy` 设置为 `dummy.next` :

l3
|
v
[L3-dummy | next] --.
|
dummy .-------------. l1
| | |
v v v
[L1-one | next] --> [L1-two | next] --> [L1-three | next] --> null

[L2-one | next] --> [L2-two | next] --> null
^
|
l2

迭代再次开始。现在让我们假设 `l1.val > l2.val` . 因此, `dummy.next` 设置为 `l2` ,  `l2` 设置为 `l2.next` 以及 `dummy` 设置为 `dummy.next` ,生成以下图像:

l3
|
v
[L3-dummy | next] --.
|
.----------------. l1
| |
v v
[L1-one | next] --. [L1-two | next] --> [L1-three | next] --> null
|
.--------------.
|
v
[L2-one | next] --> [L2-two | next] --> null
^ ^
| |
dummy l2

在下一次迭代中,我们假设 `l1.value < l2.value` . 我们将使用以下图表完成迭代:

l3
|
[L3-dummy | next] --.
|
.----------------. l2 l1
| | |
v v v
[L1-one | next] --. [L1-two | next] --> [L1-three | next] --> null
| ^
.--------------. |
| .--------------.
v |
[L2-one | next] --> [L2-two | next] --.
^
|
dummy

其他迭代只会移动 `l1` ,  `l2` 以及 `dummy` ,但不改变对象的结构。
现在请注意 `l3` 仍引用初始虚拟头,并且第一个和第二个列表中的某些引用已更改。
5t7ly7z5

5t7ly7z52#

当dummy.next语句运行时,它同时填充dummy和l3。为什么?
将一个对象指定给另一个对象时,需要在这两个对象的地址(例如dummy和l3)之间建立链接。假设-
你有一个对象(地址1000);现在,当您使用它指定另一个对象时,如下所示:
a=b
实际上,您正在以b的名义(地址为1000)制作对象a的副本。现在两个对象都指向ram中的同一个位置,无论您对一个对象所做的任何更改,它都会反映在另一个对象上。
我想你知道答案了。
额外费用:
如果代码中有问题,请进行调试以使其可接受。

相关问题