以下代码导致无限循环,尽管我在while循环中没有使用头节点。

huangapple go评论60阅读模式
英文:

The below code causing an infinite loop eventhough i didn't use head node in the while loop

问题

curr_node1curr_node2都变为null后,循环应该已经终止,但实际上它导致了一个无限循环。这是因为您在循环中没有正确地处理链表的结尾。当其中一个链表到达末尾时,您仍然在尝试访问它的next属性,这导致了无限循环。

简单来说,问题在于您没有正确地处理链表的结束条件,导致了无限循环。

英文:

After curr_node1 and curr_node2 becomes null while loop should have been terminated but instead it is causing an infinite loop. What is the reason of this can someone please explain it to me in simple words as I am a newbie.

class Node1:
    def __init__(self, data):
        self.data=data
        self.next=None



class Node2:
    def __init__(self, data):
        self.data=data
        self.next=None

def merge_sorted_ll(list1,list2):
    head=list1
    head.next=list2
    head=head.next
    curr_node1=list1
    curr_node2=list2
    while curr_node1 and curr_node2:
        curr_node1=curr_node1.next
        curr_node2=curr_node2.next
        head.next=curr_node1
        head.next.next=curr_node2
        head=head.next.next
    return head


list2=Node2(10)
list2.next=Node2(21)
list2.next.next=Node2(31)

list1=Node1(10)
list1.next=Node1(20)
list1.next.next=Node1(30)

merge_sorted_ll(list1,list2)

I want to merge two sorted linkedlist and please don't give me a corrected version of code. I know the logic is wrong but I just wanted to know why my code causing an infinite loop.

答案1

得分: 1

以下是您要翻译的内容的翻译:

可能会有助于在纸上绘制链接列表,并绘制代码对它们带来的每个更改。

当您的函数开始时,名称list1list2引用如下结构。我还包括head=list1的结果:

list1   head
┌─┴───────┴──┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data: 20   │      │ data: 30   │
│ next: ────────────┤ next: ────────────┤ next: None │
└────────────┘      └────────────┘      └────────────┘

list2
┌─┴──────────┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data: 21   │      │ data: 31   │
│ next: ────────────┤ next: ────────────┤ next: None │
└────────────┘      └────────────┘      └────────────┘

然后引入了第一个问题,因为head.next=list2覆盖了原始的next引用,因此我们失去了第一个列表的其余部分:

list1   head        (no more reference to this)
┌─┴───────┴──┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data: 20   │      │ data: 30   │
│ next: ─┐   │      │ next: ────────────┤ next: None │
└────────│───┘      └────────────┘      └────────────┘
         │
list2    │
┌─┴──────┴───┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data: 21   │      │ data: 31   │
│ next: ────────────┤ next: ────────────┤ next: None │
└────────────┘      └────────────┘      └────────────┘

接下来对名称headcurr_node1curr_node2的三个赋值导致了以下情况(我省略了我们失去引用的节点):

list1   curr_node1
┌─┴───────┴──┐
│ data: 10   │
│ next: ─┐   │
└────────│───┘
         │
list2    │
┌─┴──────┴───┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data: 21   │      │ data: 31   │
│ next: ────────────┤ next: ────────────┤ next: None │
└─┬───────┬──┘      └────────────┘      └────────────┘
head    curr_node2

现在循环开始。让我们看看每次迭代...

迭代 1

循环进入,curr_node1curr_node2沿着它们的next链接移动一步:

list1   
┌─┴──────────┐
│ data: 10   │
│ next: ─┐   │
└────────│───┘
         │
list2    │
┌─┴──────┴───┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data: 21   │      │ data: 31   │
│ next: ────────────┤ next: ────────────┤ next: None │
└─┬───────┬──┘      └───┬────────┘      └────────────┘
head    curr_node1    curr_node2

现在下一个问题出现了:赋值head.next=curr_node1将创建一个循环,因为headcurr_node1引用相同的节点:

list1   
┌─┴──────────┐
│ data: 10   │
│ next: ─┐   │
└────────│───┘
         │
list2    │ ┌───┐
┌─┴──────┴─┴─┐ │    ┌────────────┐      ┌────────────┐
│ data: 10   │ │    │ data: 21   │      │ data: 31   │
│ next: ───────┘    │ next: ────────────┤ next: None │
└─┬───────┬──┘      └───┬────────┘      └────────────┘
head    curr_node1    curr_node2

因此,head.next.nexthead相同。使用head.next.next=curr_node2将恢复链接:

list1   
┌─┴──────────┐
│ data: 10   │
│ next: ─┐   │
└────────│───┘
         │
list2    │
┌─┴──────┴───┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data: 21   │      │ data: 31   │
│ next: ────────────┤ next: ────────────┤ next: None │
└─┬───────┬──┘      └───┬────────┘      └────────────┘
head    curr_node1    curr_node2

使用head=head.next.next我们得到:

list1   
┌─┴──────────┐
│ data: 10   │
│ next: ─┐   │
└────────│───┘
         │
list2    │
┌─┴──────┴───┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data:

<details>
<summary>英文:</summary>

It may help to draw the linked lists on paper and draw each change that the code brings to them.

When your function starts, the names `list1` and `list2` are referencing the structures below. I also include the result of `head=list1`:

```none
list1   head
┌─┴───────┴──┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data: 20   │      │ data: 30   │
│ next: ────────────┤ next: ────────────┤ next: None │
└────────────┘      └────────────┘      └────────────┘

list2
┌─┴──────────┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data: 21   │      │ data: 31   │
│ next: ────────────┤ next: ────────────┤ next: None │
└────────────┘      └────────────┘      └────────────┘

Then the first problem is introduced, because head.next=list2 overwrites the original next reference, and so we lose the rest of the first list:

list1   head        (no more reference to this)
┌─┴───────┴──┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data: 20   │      │ data: 30   │
│ next: ─┐   │      │ next: ────────────┤ next: None │
└────────│───┘      └────────────┘      └────────────┘
         │
list2    │
┌─┴──────┴───┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data: 21   │      │ data: 31   │
│ next: ────────────┤ next: ────────────┤ next: None │
└────────────┘      └────────────┘      └────────────┘

The next three assignments to names head, curr_node1 and curr_node2 lead to this (I omit the nodes to which we lost any reference):

list1   curr_node1
┌─┴───────┴──┐
│ data: 10   │
│ next: ─┐   │
└────────│───┘
         │
list2    │
┌─┴──────┴───┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data: 21   │      │ data: 31   │
│ next: ────────────┤ next: ────────────┤ next: None │
└─┬───────┬──┘      └────────────┘      └────────────┘
head    curr_node2

Now the loop starts. Let's look at each iteration...

Iteration 1

The loop enters, and curr_node1 and curr_node2 move one step along their next links:

list1   
┌─┴──────────┐
│ data: 10   │
│ next: ─┐   │
└────────│───┘
         │
list2    │
┌─┴──────┴───┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data: 21   │      │ data: 31   │
│ next: ────────────┤ next: ────────────┤ next: None │
└─┬───────┬──┘      └───┬────────┘      └────────────┘
head    curr_node1    curr_node2

Now the next problem occurs: the assignment head.next=curr_node1 will create a cycle, because head and curr_node1 reference the same node:

list1   
┌─┴──────────┐
│ data: 10   │
│ next: ─┐   │
└────────│───┘
         │
list2    │ ┌───┐
┌─┴──────┴─┴─┐ │    ┌────────────┐      ┌────────────┐
│ data: 10   │ │    │ data: 21   │      │ data: 31   │
│ next: ───────┘    │ next: ────────────┤ next: None │
└─┬───────┬──┘      └───┬────────┘      └────────────┘
head    curr_node1    curr_node2

As a consequence, head.next.next is the same as just head. With head.next.next=curr_node2 the link is restored again:

list1   
┌─┴──────────┐
│ data: 10   │
│ next: ─┐   │
└────────│───┘
         │
list2    │
┌─┴──────┴───┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data: 21   │      │ data: 31   │
│ next: ────────────┤ next: ────────────┤ next: None │
└─┬───────┬──┘      └───┬────────┘      └────────────┘
head    curr_node1    curr_node2

With head=head.next.next we get:

list1   
┌─┴──────────┐
│ data: 10   │
│ next: ─┐   │
└────────│───┘
         │
list2    │
┌─┴──────┴───┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data: 21   │      │ data: 31   │
│ next: ────────────┤ next: ────────────┤ next: None │
└────────┬───┘      └───────┬────┘      └────┬───────┘
   curr_node1         curr_node2           head

Iteration 2

The two curr references are moved one step again, and so we get:

list1   
┌─┴──────────┐
│ data: 10   │
│ next: ─┐   │
└────────│───┘
         │
list2    │
┌─┴──────┴───┐      ┌────────────┐      ┌────────────┐
│ data: 10   │      │ data: 21   │      │ data: 31   │
│ next: ────────────┤ next: ────────────┤ next: None │
└────────────┘      └──────┬─────┘      └──┬─────┬───┘
                     curr_node1      curr_node2 head

Now head.next=curr_node1 will create a greater cycle:

list1   
┌─┴──────────┐
│ data: 10   │
│ next: ─┐   │
└────────│───┘
         │
list2    │                   ┌─────────────────────┐
┌─┴──────┴───┐      ┌────────┴───┐      ┌──────────│─┐
│ data: 10   │      │ data: 21   │      │ data: 31 │ │
│ next: ────────────┤ next: ────────────┤ next: ───┘ │
└────────────┘      └──────┬─────┘      └──┬─────┬───┘
                     curr_node1      curr_node2 head

And the next head.next.next=curr_node2 assignment will do nothing, because the references at both sides of the = are already equal. Also head=head.next.next will not accomplish anything for the same reason.

Iteration 3

This iteration starts with a state where the list has a cycle with size 2, and so the first two assignments will swap the two cur references:

list1   
┌─┴──────────┐
│ data: 10   │
│ next: ─┐   │
└────────│───┘
         │
list2    │                   ┌─────────────────────┐
┌─┴──────┴───┐      ┌────────┴───┐      ┌──────────│─┐
│ data: 10   │      │ data: 21   │      │ data: 31 │ │
│ next: ────────────┤ next: ────────────┤ next: ───┘ │
└────────────┘      └──────┬─────┘      └──┬─────┬───┘
                     curr_node2      curr_node1 head

head.next=curr1 will create the self-reference again, and head.next.next=curr_node2 will revert that change. head=head.next.next will not accomplish anything: the structure of the linked list at the end of this iteration is the same as when the iteration started.

Only the two cur references got swapped. The fourth iteration will do the opposite swap, ...etc, and so we have an infinite loop.

答案2

得分: 0

在你的 while 循环中,while curr_node1 and curr_node2,你没有设置退出条件。当前,这个 while 循环一直在检查这两个对象是否存在,而它们存在,因此它会一直循环运行。你需要在循环中设置一些内容来跳出循环,可以通过使条件为假或在某个地方包含一个 break 语句来实现。

英文:

In your while loop, while curr_node1 and curr_node2, you don't have an exit condition. Right now, the while loop is checking to see if those two objects exist, which they do, so it will always run in a loop. You need to have something to break out of that loop, either by making the conditional false or including a break statement somewhere.

huangapple
  • 本文由 发表于 2023年5月17日 23:36:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76273829.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定