如何实现无返回值单参数的C语言链表递归反转函数?
递归反转链表(无返回值、仅传头指针地址)
给定链表节点结构体
typedef struct _listnode { int item; struct _listnode *next; } ListNode;
原代码问题分析
你提供的递归反转代码存在核心问题:递归完成后没有更新原链表的头指针指向反转后的新表头。
递归调用reverseList(&rest)确实反转了first->next起始的子链表,但反转结束后,rest实际指向的是原first->next子链表的尾节点(即反转后子链表的最后一个节点),而非子链表反转后的新头。后续仅将rest->next指向first,但原*headptr仍指向最初的第一个节点,导致外部只能访问到该节点,其余反转后的元素无法被遍历到。
正确实现代码
void reverseList(ListNode **headptr) { // 终止条件:空链表或仅一个节点,无需反转 if (*headptr == NULL || (*headptr)->next == NULL) return; ListNode *first = *headptr; ListNode *rest = first->next; // 递归反转剩余子链表 reverseList(&rest); // 将当前节点挂载到反转后子链表的末尾 first->next->next = first; first->next = NULL; // 更新原头指针,指向反转后的新链表头(原链表的尾节点) *headptr = rest; }
关键逻辑说明
- 终止条件简化:直接处理空链表或单节点场景,避免冗余判断。
- 递归反转子链表:递归调用会将
rest对应的子链表完全反转,且rest最终会被更新为该子链表反转后的新头节点(也就是原整个链表的最后一个节点)。 - 挂载当前节点:
first->next是反转前子链表的首节点,反转后它成为子链表的尾节点,将其next指向first,就能把当前节点接到子链表末尾。 - 更新头指针:必须将
*headptr赋值为rest,这样外部传入的头指针变量会被修改为反转后的新表头,确保外部能完整访问反转后的链表。
测试示例
#include <stdio.h> #include <stdlib.h> // 链表节点结构体(重复定义仅为测试完整) typedef struct _listnode { int item; struct _listnode *next; } ListNode; void reverseList(ListNode **headptr); void printList(ListNode *head); int main() { // 构建测试链表:1->2->3->4->NULL ListNode *head = (ListNode*)malloc(sizeof(ListNode)); head->item = 1; head->next = (ListNode*)malloc(sizeof(ListNode)); head->next->item = 2; head->next->next = (ListNode*)malloc(sizeof(ListNode)); head->next->next->item = 3; head->next->next->next = (ListNode*)malloc(sizeof(ListNode)); head->next->next->next->item = 4; head->next->next->next->next = NULL; printf("原链表:"); printList(head); reverseList(&head); printf("反转后链表:"); printList(head); // 释放链表内存(示例省略具体释放逻辑) return 0; } void printList(ListNode *head) { ListNode *curr = head; while (curr != NULL) { printf("%d ", curr->item); curr = curr->next; } printf("\n"); }
运行后会输出:
原链表:1 2 3 4 反转后链表:4 3 2 1
内容的提问来源于stack exchange,提问作者Centauri_42
相关产品推荐
相关产品推荐

