链表中间节点查找:为何交换&&条件顺序会引发运行时错误?
寻找链表中间节点
题目描述
给定一个包含N个节点的单链表,任务是找到链表的中间节点:
- 若节点数为奇数,返回中间节点;
- 若为偶数,返回第二个中间节点。
例如:
- 链表
1->2->3->4->5的中间节点是3; - 链表
1->2->3->4->5->6的中间节点是4。
示例
- 示例1:
输入:链表1->2->3->4->5
输出:3
解释:链表中间节点为3。 - 示例2:
输入:链表2->4->6->7->5->1
输出:7
解释:链表中间节点为7。
任务要求
完成getMiddle()函数,接收头节点引用作为参数,返回中间节点的数据。
- 预期时间复杂度:O(N)
- 辅助空间复杂度:O(1)
- 约束:1<=N<=5000
两段代码对比
第一段代码(运行报错)
class Solution{ public: /* Should return data of middle node. If linked list is empty, then -1*/ int getMiddle(Node *head) { Node* fast = head; Node *slow = head; if (head != NULL){ while(fast->next != NULL && fast != NULL) // 此处条件顺序 { fast = fast->next->next; slow = slow->next; } } return slow->data; } }; // Runtime Error: Segmentation Fault (SIGSEGV)
第二段代码(运行成功)
class Solution{ public: /* Should return data of middle node. If linked list is empty, then -1*/ int getMiddle(Node *head) { Node* fast = head; Node *slow = head; if (head != NULL){ while(fast != NULL && fast->next != NULL) // 此处条件顺序 { fast = fast->next->next; slow = slow->next; } } return slow->data; } }; // Problem Solved Successfully
问题
请问为何交换&&的条件顺序会导致结果不同?
解答
核心原因是逻辑与运算符(&&)的短路求值特性:当&&左边的条件为假时,右边的条件会直接被跳过,不会执行。
- 第一段代码的循环条件
fast->next != NULL && fast != NULL存在致命问题:当fast已经是NULL时,代码会先尝试访问fast->next——空指针的成员,这直接触发了段错误(SIGSEGV)。比如处理偶数节点的链表时,最后一次循环后fast会变为NULL,下一次循环检查条件时,先执行fast->next就会直接崩溃。 - 第二段代码把条件顺序改为
fast != NULL && fast->next != NULL:先检查fast是否为空,只有fast有效时才会去访问fast->next,从根源上避免了空指针访问的情况,因此能正常运行。
举个具体场景:链表1->2->3->4(偶数节点)
- 第一次循环:
fast从1跳到3,slow从1跳到2; - 第二次循环:
fast从3跳到NULL,slow从2跳到3; - 下一次循环检查条件时:
- 第一段代码先判断
fast->next,此时fast是NULL,直接触发段错误; - 第二段代码先判断
fast != NULL,结果为假,直接跳过右边的条件,循环终止,程序正常返回slow->data。
- 第一段代码先判断
内容的提问来源于stack exchange,提问作者Leo Chiu
相关产品推荐
相关产品推荐

