c语言描述 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 输入描述 示例 1 rev1ex1.jpg 输入:head = [1,2,3,4,5] 输出:[5,4,3,2,1] 示例 2: rev1ex2.jpg 输入:head = [1,2] 输出:[2,1] 输出描述 略 用例输入 1 1 2 3 4 5 6 用例输出 1 6 5 4 3 2 1 用例输入 2 1 2 用例输出 2 2 1
时间: 2025-06-27 17:11:38 AIGC 浏览: 21
### 反转单链表的C语言实现
在C语言中,可以通过迭代的方式反转单链表。以下是基于提供的参考资料[^3]所描述的方法编写的函数。
#### 函数定义
以下是一个完整的 `reverseList` 函数实现:
```c
#include <stdio.h>
#include <stdlib>
// 定义链表节点结构体
struct ListNode {
int val;
struct ListNode *next;
};
// 反转链表的函数
struct ListNode* reverseList(struct ListNode* head) {
if (head == NULL || head->next == NULL) { // 如果链表为空或者只有一个节点,则直接返回头节点
return head;
}
struct ListNode* prev = NULL; // 前驱节点初始化为NULL
struct ListNode* curr = head; // 当前节点初始化为头节点
struct ListNode* nextNode = NULL; // 下一节点暂存变量
while (curr != NULL) { // 遍历整个链表直到当前节点为空
nextNode = curr->next; // 暂存下一节点
curr->next = prev; // 将当前节点的next指向前驱节点,完成反转操作
prev = curr; // 更新前驱节点为当前节点
curr = nextNode; // 移动到下一节点继续处理
}
return prev; // 返回新的头节点(即原来的尾节点)
}
```
上述代码通过三个指针变量 (`prev`, `curr`, 和 `nextNode`) 来逐步遍历并反转链表中的每一个节点连接关系。
---
#### 示例输入输出说明
假设有一个单链表如下所示:
```
1 -> 2 -> 3 -> 4 -> 5
```
调用 `reverseList` 后的结果将是:
```
5 -> 4 -> 3 -> 2 -> 1
```
##### 输入示例
创建一个简单的测试程序来验证功能:
```c
int main() {
// 创建链表 1 -> 2 -> 3 -> 4 -> 5
struct ListNode* node5 = malloc(sizeof(struct ListNode));
node5->val = 5;
node5->next = NULL;
struct ListNode* node4 = malloc(sizeof(struct ListNode));
node4->val = 4;
node4->next = node5;
struct ListNode* node3 = malloc(sizeof(struct ListNode));
node3->val = 3;
node3->next = node4;
struct ListNode* node2 = malloc(sizeof(struct ListNode));
node2->val = 2;
node2->next = node3;
struct ListNode* head = malloc(sizeof(struct ListNode));
head->val = 1;
head->next = node2;
printf("Original List:\n");
struct ListNode* temp = head;
while (temp != NULL) {
printf("%d ", temp->val);
temp = temp->next;
}
// 调用反转函数
struct ListNode* newHead = reverseList(head);
printf("\nReversed List:\n");
temp = newHead;
while (temp != NULL) {
printf("%d ", temp->val);
temp = temp->next;
}
return 0;
}
```
运行此程序将打印原始链表和反转后的链表内容。
---
#### 关键点解析
1. **边界条件**
- 若链表为空或仅含一个节点,则无需任何操作,直接返回原头节点即可。
2. **三指针法**
使用 `prev`、`curr` 和 `nextNode` 这三个指针分别表示前驱节点、当前节点以及下一个待处理节点,在每次循环中调整它们之间的链接方向。
3. **时间复杂度与空间复杂度**
- 时间复杂度:O(n),其中 n 是链表长度,因为每个节点都需要访问一次。
- 空间复杂度:O(1),只用了常数级别的额外存储空间。
---
阅读全文