单向链表反转实现
问题分析 需要实现一个函数,将输入的单向链表进行反转操作。原链表头节点变为新链表尾节点,原尾节点变为新头节点。链表节点结构定义如下:
struct ListNode {
int data;
struct ListNode *next;
};
目标函数原型为:
struct ListNode *reverse(struct ListNode *head);
该函数接收链表头指针,返回反转后的新链表头。
核心逻辑 通过三指针法完成链表反转:维持前驱、当前和后继三个指针,逐步调整指针方向。
- 初始化
prev为NULL,curr为链表头。 - 在遍历过程中,先保存当前节点的下一个节点。
- 将当前节点的
next指针指向prev,完成反转。 - 同时更新
prev和curr指针,向前推进。 - 当
curr为空时,prev即为新的链表头。
代码实现
#include <stdio.h>
#include <stdlib.h>
struct ListNode {
int data;
struct ListNode *next;
};
// 反转链表函数
struct ListNode *reverse(struct ListNode *head) {
struct ListNode *prev = NULL;
struct ListNode *current = head;
struct ListNode *next_node = NULL;
while (current != NULL) {
next_node = current->next; // 保存下一节点
current->next = prev; // 反转指针方向
prev = current; // 移动prev
current = next_node; // 移动current
}
return prev; // 返回新头节点
}
// 创建链表(以-1为结束标志)
struct ListNode *create_list() {
int val;
struct ListNode *head = NULL;
struct ListNode *tail = NULL;
while (scanf("%d", &val) && val != -1) {
struct ListNode *node = (struct ListNode *)malloc(sizeof(struct ListNode));
node->data = val;
node->next = NULL;
if (head == NULL) {
head = node;
tail = node;
} else {
tail->next = node;
tail = node;
}
}
return head;
}
// 打印链表内容
void print_list(struct ListNode *head) {
struct ListNode *p = head;
while (p != NULL) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main() {
struct ListNode *list_head;
// 输入并构建链表
list_head = create_list();
// 反转链表
list_head = reverse(list_head);
// 输出结果
print_list(list_head);
return 0;
}
关键点说明
next_node用于临时保存当前节点的后续节点,防止链路断裂。prev始终指向已处理部分的末尾,最终成为新链表的头。- 整个过程仅需一次遍历,无需额外存储空间。
测试示例 输入:
1 2 3 4 5 6 -1
输出:
6 5 4 3 2 1
复杂度分析
- 时间复杂度: O(n),仅需遍历每个节点一次。
- 空间复杂度: O(1),仅使用固定数量的指针变量。
总结 本实现采用经典的双指针迭代方法,高效且稳定地完成链表反转。算法简洁,无递归开销,适用于任意长度链表,是链表操作中的经典范例。
