
#include <iostream>
#include <vector>
// 定义链表节点结构体
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
class Solution {
public:
/**
* 反转单链表 - 迭代法
* * 算法思路:
* 1. 定义两个指针:prev (前驱节点) 和 curr (当前节点)。
* 2. 初始化 prev 为 nullptr,curr 为 head。
* 3. 遍历链表,每次循环中:
* a. 先暂存 curr 的下一个节点 (nextTemp),因为改变指向后会丢失后续节点。
* b. 将 curr->next 指向 prev,完成当前节点的反转。
* c. 将 prev 和 curr 分别向后移动一步。
* 4. 循环结束后,prev 将指向原链表的尾部(即新链表的头部),返回 prev。
*/
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr != nullptr) {
ListNode* nextTemp = curr->next; // 1. 暂存后继节点
curr->next = prev; // 2. 修改引用指向前驱
prev = curr; // 3. prev 向后移动
curr = nextTemp; // 4. curr 向后移动
}
return prev; // 返回新的头节点
}
};
// --- 以下是辅助函数,用于测试代码 ---
// 辅助函数:根据数组创建链表
ListNode* createList(const std::vector<int>& vals) {
if (vals.empty()) return nullptr;
ListNode* head = new ListNode(vals[0]);
ListNode* curr = head;
for (size_t i = 1; i < vals.size(); ++i) {
curr->next = new ListNode(vals[i]);
curr = curr->next;
}
return head;
}
// 辅助函数:打印链表
void printList(ListNode* head) {
ListNode* curr = head;
std::cout << "[";
while (curr != nullptr) {
std::cout << curr->val;
if (curr->next != nullptr) std::cout << ", ";
curr = curr->next;
}
std::cout << "]" << std::endl;
}
// 辅助函数:释放链表内存
void deleteList(ListNode* head) {
while (head != nullptr) {
ListNode* temp = head;
head = head->next;
delete temp;
}
}
int main() {
Solution solution;
// 示例 1
std::cout << "示例 1:" << std::endl;
std::vector<int> v1 = {1, 2, 3, 4, 5};
ListNode* l1 = createList(v1);
std::cout << "输入: "; printList(l1);
ListNode* res1 = solution.reverseList(l1);
std::cout << "输出: "; printList(res1);
deleteList(res1);
std::cout << "-------------------" << std::endl;
// 示例 2
std::cout << "示例 2:" << std::endl;
std::vector<int> v2 = {1, 2};
ListNode* l2 = createList(v2);
std::cout << "输入: "; printList(l2);
ListNode* res2 = solution.reverseList(l2);
std::cout << "输出: "; printList(res2);
deleteList(res2);
std::cout << "-------------------" << std::endl;
// 示例 3 (空链表)
std::cout << "示例 3:" << std::endl;
std::vector<int> v3 = {};
ListNode* l3 = createList(v3);
std::cout << "输入: "; printList(l3);
ListNode* res3 = solution.reverseList(l3);
std::cout << "输出: "; printList(res3); // 应该输出 []
deleteList(res3);
return 0;
}
代码解析
-
核心逻辑 (
reverseList函数):-
我们定义了
prev(初始化为nullptr) 和curr(初始化为head)。 -
在
while循环中,核心步骤是curr->next = prev,这一步实际上切断了原来的链接并建立了反向链接。 -
最后返回
prev,因为当循环结束时,curr变成了nullptr,而prev正好停在原链表的最后一个节点(也就是新链表的头节点)。
-
-
复杂度分析:
-
时间复杂度: O(n),其中 n 是链表的长度。我们需要遍历链表一次。
-
空间复杂度: O(1)。我们只使用了几个指针变量,没有使用与链表长度相关的额外空间。
-