链表倒数第n个节点获取异常求助:反转链表后函数无输出且无报错
问题排查与解决方案
嘿,我一眼就看到你getNode函数里的循环逻辑出问题了,这就是程序卡在那里没输出的核心原因!咱们一步步拆解:
首先看这段有问题的代码:
while (ptr != NULL) { if (count == positionFromTail) { return (ptr->data); count = count + 1; ptr = ptr->next; } }
这里有两个致命错误:
- 一旦
count等于目标位置,函数直接return了,后面的count++和指针移动代码根本没机会执行——这还不是最糟的,如果第一次循环count不等于目标值,整个循环里没有任何推进指针或计数的操作,直接陷入无限循环!程序就卡在这里,永远到不了printf那一步。 - 你把指针和计数的更新放在了
return之后,这部分代码完全是不可达的,相当于写了白写。
先给你修正反转链表的实现
把计数和指针移动的代码放到if判断外面,确保每次循环都能推进:
int getNode(struct Node* head, int positionFromTail) { struct Node* prevNode = NULL; struct Node* currNode = head; struct Node* nextNode; // 反转链表的逻辑是没问题的 while (currNode != NULL) { nextNode = currNode->next; currNode->next = prevNode; prevNode = currNode; currNode = nextNode; } struct Node* ptr = prevNode; // 反转后的头节点是prevNode,修改head没用(传值调用不影响外部) int count = 0; while (ptr != NULL) { if (count == positionFromTail) { return ptr->data; } // 不管条件满足与否,都要推进指针和计数 count++; ptr = ptr->next; } assert(0); // 走到这说明positionFromTail超出链表长度 }
额外推荐:更高效的双指针法(不用反转链表)
其实找倒数第n个节点根本不需要反转整个链表,用双指针技巧可以做到O(n)时间、O(1)空间,还不会修改原链表结构:
int getNode(struct Node* head, int positionFromTail) { struct Node* fast = head; struct Node* slow = head; // 先让fast指针先走positionFromTail+1步 for (int i = 0; i <= positionFromTail; i++) { assert(fast != NULL); // 防止传入的位置超出链表长度 fast = fast->next; } // 两个指针一起走,fast到末尾时,slow就是倒数第positionFromTail个节点 while (fast != NULL) { fast = fast->next; slow = slow->next; } return slow->data; }
这个方法更优雅,也避免了反转链表可能带来的潜在问题(比如如果后续还要使用原链表的话)。
测试结果
用你的测试链表3->2->1->0,调用getNode(head, 2),目标是倒数第2个节点(值为1),修正后的代码都会正确返回1,程序会输出The value of the node is 1。
内容的提问来源于stack exchange,提问作者Onesimus Chandra Pradhan
相关产品推荐
相关产品推荐

