1. 原地反转
- 设立虚拟头节点指向原头节点,利用双指针确定begin和end。
- 让begin->next指向end->next。
- 再使end->next指向begin。
- 最后使虚拟头节点指向end。
- 最后移动end指向的节点,使其指向begin后一个节点。
- 核心在于:使用虚拟头节点和双指针,end指针始终指向1节点之后的节点,将end指针所指向节点依次移动到虚拟头节点后。
- 代码实现:
struct ListNode* reverseList(struct ListNode* head) { // 定义一个虚拟头节点 struct ListNode* DummyHead = (struct ListNode*)malloc(sizeof(struct ListNode)); // 初始化,使虚拟头节点指向链表头节点 DummyHead->next = head; DummyHead->val = 0; // 判断原链表头节点是否为空或是否只有一个节点,否则后续会报错 if (NULL == head || NULL == head->next) { return head; } // 定义双指针 struct ListNode* begin = head; struct ListNode* end = head->next; // 当end指针不为空时,依次将end指向节点返回到虚拟头节点之后 while (end) { begin->next = end->next; end->next = DummyHead->next; DummyHead->next = end; // 定义新的end指针指向 end = begin->next; } return DummyHead->next; }
2. 头插法
- 定义一个NewHead为空,创建NewNode,使NewNode->val=head->val。
- 这一步是创建了一个新链表。
- 使NewHead=NewNode。
创建新的NewNode。
使head=head->next,使NewNode->val=head->val。
- 核心在于:不断移动NewHead的位置,使NewNode始终以头插的方式进入新链表。
- 代码实现
struct ListNode* reverseList(struct ListNode* head) { //定义一个新的节点使其为空 struct ListNode* NewHead = NULL; while (head) { //不断插入新的第一个节点 struct ListNode* NewNode = (struct ListNode*)malloc(sizeof(struct ListNode)); NewNode->next = NewHead; NewNode->val = head->val; head = head->next; //利用NewHead的位置改变实现头插 NewHead = NewNode; } return NewHead; }
3. 迭代法
- 因为反转后的头节点指向空,所以定义空指针first,使其指向头节点。
- 定义second指向head。
- third=second->next记录下一个节点。
- 令second->next=first,实现前两个节点的反转。
- 使second=third,third=third->next。
- first指向自己的下一个节点。
- 继续反转,使second->next=first。
- 核心在于:利用三指针的遍历,不断反转使second指向first,third记录second后的断点。
- 代码实现:
struct ListNode* reverseList(struct ListNode* head) { //定义双指针 struct ListNode* second = head; struct ListNode* first = NULL; while (second) { //定义第三个指针,以记录second的下一个节点 struct ListNode* third = second->next; //断后连前 second->next = first; first = second; second = third; } return first; }
4. 递归法
- 递归法的思路与迭代法类似,可以看作把迭代法写成了递归形式
- 代码实现:
struct ListNode* Reverse(struct ListNode* first, struct ListNode* second) { //判断头节点是否为空或者头节点下一个节点是否为空 if (!second){ return first; } //记录second指针后一个节点 struct ListNode* third = second->next; second->next = first; // 将second作为first传入下一层 // 将third作为second传入下一层,改变其指针指向当前second return Reverse(second, third); } struct ListNode* reverseList(struct ListNode* head) { return Reverse(NULL, head); }
5. 栈实现反转
- 将链表元素从头存入栈中。
- 将栈顶元素出栈,作为反转后链表的头节点。
- 全部出栈之后需要让尾节点指向空。
- 核心在于:利用栈先进后出的特点反转链表
- 代码实现:
struct ListNode* reverseList(struct ListNode* head) { // 判断头节点是否为空或者头节点下一个节点是否为空 if (head == NULL || head->next == NULL) { return head; } int size = 0; struct ListNode* p = head; // 求链表长度 while (p != NULL) { size++; p = p->next; } // 创建栈 struct ListNode* stack[size]; int top = -1; p = head; // 将链表存入栈中 while (p != NULL) { stack[++top] = p; p = p->next; } // 创建反转链表的头节点 struct ListNode* head2 = stack[top]; p = head2; // 将反转的链表存入 while (top != -1) { p->next = stack[top--]; p = p->next; } // 不能忘记尾节点指向空 p->next = NULL; return head2; }











2250

被折叠的 条评论
为什么被折叠?



