关于链表遍历和调试的困惑

Confusion about linked list traversal and debugging

本文关键字:调试 遍历 于链表 链表      更新时间:2023-10-16

我正在练习链表,我不确定这里出了什么问题。

在第一个实现中,我做了一个 ListNode* 结果并赋予它任何值,当我不返回 dummyhead,而是返回 dummyhead->next (resultHead->next(。

这按预期工作。

/**
* Definition for singly-linked list.
* struct ListNode {
*     int val;
*     ListNode *next;
*     ListNode(int x) : val(x), next(NULL) {}
* };
*/

法典:

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* result = new ListNode(0);
ListNode* resultHead = result;
int carry(0);
while(l1 || l2 || carry) {
int val1 = l1 ? l1->val : 0;
int val2 = l2 ? l2-> val : 0;
int sum(val1 + val2 + carry);
carry = sum/10;
ListNode* l3 = new ListNode(sum % 10);
result->next = l3;
result = result->next;
if(l1) l1 = l1->next;
if(l2) l2 = l2->next;
}
return resultHead->next;
}

现在我想如果我最初给它一个nullptr检查 null 并为其分配新节点并像以前一样继续,也许我可以避免这种情况,但在这种情况下,在调试器之后,列表开始丢失元素,当我做result = result->next.

法典:

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* result = NULL; // also tried nullptr
ListNode* resultHead = result;
int carry(0);
while(l1 || l2 || carry) {
int val1 = l1 ? l1->val : 0;
int val2 = l2 ? l2-> val : 0;
int sum(val1 + val2 + carry);
carry = sum/10;
ListNode* l3 = new ListNode(sum % 10);
if(!result) result = l3;
else {
result->next = l3;
result = result->next;
}
if(l1) l1 = l1->next;
if(l2) l2 = l2->next;
}
return resultHead;
}

我看到的一个问题是结果头没有得到更新,这 我猜是要处理的事情(更新 if 中的条件 块(

,但是为什么列表不能以这种方式正确制作呢? 背后的原因是什么?

编辑:

Input lists
l1: [2,4,3]
l2: [5,6,4]
It assigns 7 to "result" in first pass
In second pass the list becomes [7,0] at the `result->next = l3` step in the else block but at the result = result->next the list becomes [0];

问题只是没有更新resultHead(我知道如何修复并且需要修复,但我认为我应该检查列表是否正常(同时遵循 linkedlist 它一次只指向一个元素,这让我很震惊 关闭(第一次调试链表(,此时的值为 0 巧合地导致我 错误地认为列表为空,但事实并非如此 箱。

编辑:我的问题也是不熟悉调试链表,随着我们的前进,它应该只显示前面的元素。

这基本上是你的第一个代码所做的:

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* result = new ListNode(0);
ListNode* resultHead = result;
while(l1 || l2 ) {
ListNode* l3 = new ListNode(0);
result->next = l3;
result = result->next;
if(l1) l1 = l1->next;
if(l2) l2 = l2->next;
}
return resultHead->next;
}

一开始有一个节点,比如n0(resultresultHead指向它(。在循环中的每个回合,您都在结果后面添加一个新节点,因此 n0->n1,然后是 n0->n1->n2,依此类推。最后你返回 n1,因此列表 n1->n2->...

在第二种情况下:

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* result = NULL; // also tried nullptr
ListNode* resultHead = result;
while(l1 || l2 || carry) {
ListNode* l3 = new ListNode(0);
if(!result) result = l3;
else {
result->next = l3;
result = result->next;
}
if(l1) l1 = l1->next;
if(l2) l2 = l2->next;
}
return resultHead;
}

一开始你有resultresultHead等于空。因此,无论循环中发生什么(它对resultHead没有任何作用(,你只是返回resultHead这是空的。如果出现以下情况,您可以修改内部的阳性情况:

if(!result) {
result = l3;
resultHead = result;
}

因此,在最后,resultHead将等于第一个创建的节点。