C++ 链表删除倒数第 n 个结点代码分析及优化
这段 C++ 代码用于实现删除链表的倒数第 n 个结点,并返回链表的头结点。代码中存在一些漏洞,需要进行优化:
-
当链表中只有一个结点且需要删除时,没有考虑返回 NULL 的情况。在
removeNthFromEnd函数中,需要加上判断链表只有一个结点且需要删除的情况。 -
在
di函数中,m-n == k的判断条件不正确,应该是m-n == n-1。因为 n 是倒数第 n 个结点,所以删除的是第 m 个结点,即 m-n+1 个结点,而当前循环的是第 k 个结点,所以m-n+1 == k-1,即m-n == k-2,而需要删除的是倒数第 n 个结点,所以k-2 == n-1。 -
在
di函数中,返回值 m 的含义不清晰,应该改为返回当前结点的位置 i。因为需要删除的是倒数第 n 个结点,所以需要找到倒数第 n+1 个结点,即第 i-n 个结点,而当前循环的是第 i 个结点,所以 i-n 就是需要删除的结点。 -
在
di函数中,k 的初始值应该为 1,而不是 0。因为当前循环的是第 k 个结点,而不是第 k-1 个结点。
以下是优化后的代码:
int di(ListNode* L, int n, int k) {
if (L == NULL) {
if (k - 1 == n) return -1; // 删除头结点,返回第二个结点即可
return k - 1;
}
int i = di(L->next, n, k + 1); // 递归调用,计算当前节点的位置
if (i - n == n - 1) { // 找到倒数第 n+1 个节点
ListNode* q = L->next;
L->next = q->next;
delete(q);
return i - 1; // 返回头结点的位置
}
return i; // 返回当前节点的位置
}
ListNode* removeNthFromEnd(ListNode* head, int n) {
if (head == NULL) {
return head;
}
if (head->next == NULL && n == 1) { // 链表只有一个节点且需要删除
delete(head);
return NULL;
}
int x = di(head, n, 1);
if (x == -1) {
ListNode* q = head;
head = head->next;
delete(q);
}
return head;
}
优化后的代码修复了之前的漏洞,并提高了代码的可读性和可维护性。代码中使用了递归的方式来计算当前结点的位置,并通过判断条件 i-n == n-1 来找到需要删除的结点。
通过这些优化,代码能够正确实现删除链表倒数第 n 个结点的功能,并且代码更加健壮和易于理解。
原文地址: https://www.cveoy.top/t/topic/ntIg 著作权归作者所有。请勿转载和采集!