前言:
1、使用的本地IDE是Visual Studio 2022(下文简称VS)
2、VS的一些调试操作
Ctrl + Fn + F5
运行程序
Ctrl + Fn + F10
从main函数开始一步步执行(光标要先点到main函数那儿)
Fn + F10
每次执行一行语句,如果碰到函数调用,则把函数调用当成一条语句执行
Fn + F11
每次执行一行语句,如果碰到函数调用,则进入到函数内部一行行执行
Ctrl + Fn + F7
启动生成程序,看有几个错误
3、如何Debug?(摘自代码随想录算法训练营每日精华,内有更多干货,欢迎各位加入)
本次调试采用2+3,在ChatGPT的基础上进行修改,得到自己想要的结果。不得不说,比自己想省事多了。
206.反转链表
正确代码如下:
class Solution {
public:
ListNode* reverse(ListNode* cur, ListNode* pre){
if(cur == NULL) return pre;
ListNode* tmp = cur->next;
cur->next = pre;
//上面一次翻转已完成,于是进入下一次
return reverse(tmp, cur);
}
ListNode* reverseList(ListNode* head) {
return reverse(head, NULL);
}
};
自己写的时候出现的问题:
return reverse(tmp, cur);
这一句代码没有加上return
。
先说结论:
若不加return
,则无法将pre
带到最外层出来。函数reverse()
不断递归,进入最内层,满足了条件if(cur == NULL) return pre;
后只有一个return
把pre
停留在倒数第二层。
Debug过程:
1、问一下ChatGPT:“这是我的代码,可以帮我修改一下实现可视化递归过程吗?” 然后就给了我一段代码,再自己修改一下。
2、学习了GPT链表的建立和链表的打印,没我想得那么复杂hhh。
3、在相关的地方建个变量,每次进入递归或者从递归出来进行++再打印就行。我建了个全局变量int i = 1;
并且用调试Fn + F10
和 Fn + F11
一步步看是怎么走的,就发现问题了。
GPT给的代码如下:
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
void printList(ListNode* head) {
ListNode* curr = head;
while (curr != NULL) {
std::cout << curr->val << " ";
curr = curr->next;
}
std::cout << std::endl;
}
ListNode* reverse(ListNode* cur, ListNode* pre) {
if (cur == NULL) return pre;
cout << "Reversing: ";
printList(cur);
ListNode* tmp = cur->next;
cur->next = pre;
ListNode* newHead = reverse(tmp, cur);
cout << "Returning newHead end: ";
printList(newHead);
return newHead;
}
ListNode* reverseList(ListNode* head) {
cout << "Returning head: " << head->val << endl;
return reverse(head, NULL);
}
int main() {
ListNode* head = new ListNode(1);
ListNode* node2 = new ListNode(2);
ListNode* node3 = new ListNode(3);
ListNode* node4 = new ListNode(4);
ListNode* node5 = new ListNode(5);
head->next = node2;
node2->next = node3;
node3->next = node4;
node4->next = node5;
// 反转链表
ListNode* newHead = reverseList(head);
// 打印反转后的链表
std::cout << "Reversed list: ";
printList(newHead);
return 0;
}
我修改后的完整代码如下(没有写入return的):
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
void printList(ListNode* head) {
ListNode* curr = head;
while (curr != NULL) {
std::cout << curr->val << " ";
curr = curr->next;
}
std::cout << std::endl;
}
//建一个全局变量
int i = 1;
ListNode* reverse(ListNode* cur, ListNode* pre) {
if (cur == NULL) return pre;
cout << "Reversing: ";
printList(cur);
ListNode* tmp = cur->next;
cur->next = pre;
//cout << "Returning newHead: ";
//ListNode* newHead = reverse(tmp, cur);
reverse(tmp, cur);
cout << "开始返回第 " << i << "轮" << endl;
i++;
cout << endl;
//cout << "Returning newHead end: ";
//printList(newHead);
//return newHead;
}
ListNode* reverseList(ListNode* head) {
//cout << "Returning head: " << head->val << endl;
return reverse(head, NULL);
}
int main() {
ListNode* head = new ListNode(1);
ListNode* node2 = new ListNode(2);
ListNode* node3 = new ListNode(3);
ListNode* node4 = new ListNode(4);
ListNode* node5 = new ListNode(5);
head->next = node2;
node2->next = node3;
node3->next = node4;
node4->next = node5;
// 反转链表
ListNode* newHead = reverseList(head);
// 打印反转后的链表
std::cout << "Reversed list: ";
printList(newHead);
return 0;
}
结果如下:
可以看到递归进入到函数最内层后一层层返回(体现在i
值的变化)。且没有return
的情况下,最终的结果是错误的。原因就是没有把pre
从最内层带到最外层。
这个过程中还发现了一个问题: 若把int i = 1
建在函数reverse()
里面,不管是放在递归之前还是递归之后,最终的结果都是每次碰到函数reverse()
就会把i
置为1,我也不知道为什么放在递归之后也会这样。
把return
加回去结果就正常了,如下图所示: