0、题目描述
1、法1
思路是改变链表的指针方向,本来箭头向右改向左。问题是改变箭头之后链表就无法继续往下走了,所以需要3个指针,利用迭代的办法往下走。
struct ListNode* reverseList(struct ListNode* head)
{
if (head == NULL)
{
return NULL;
}
struct ListNode* p1 = NULL;
struct ListNode* p2 = head;
struct ListNode* p3 = head->next;
while (p2)//p2是更改指针方向的节点,p2为空,说明没有节点需要更改了
{
p2->next = p1;
p1 = p2;
p2 = p3;
if (p3) //防止p3越界访问,p3为空的时候就停止移动
p3 = p3->next;
}
return p1;//退出while循环的时候,p2为空,p1是第一个节点
}
2、法2
创建一个新的头结点newhead,然后把原来的链表节点头插到新的节点里。注意在这个过程里cur->next找不到了,需要提前保存一下。以便链表继续遍历。
struct ListNode* reverseList(struct ListNode* head)
{
struct ListNode* cur = head;
struct ListNode* newhead = NULL;
while (cur)
{
struct ListNode* next = cur->next;
//头插
cur->next = newhead;
newhead = cur;
cur = next;
}
return newhead;
}
3、法3
递归,递归和上面的循环有相似的地方,不过不太好理解。
struct ListNode* reverseList(struct ListNode* head) {
if (head == NULL || head->next == NULL) {
return head;
}
struct ListNode* newHead = reverseList(head->next);
//这句代码实际上是head和head->next两个节点互指,你指向我,我指向你
//如果需要更改,这句代码就会给就会把head->next这个节点下一个指针指向前一个节点
head->next->next = head;
//这实际上是为最后一次递归服务
//如何解决上句代码互指的问题,要么进入下次递归改head->next,要么置空
head->next = NULL;
return newHead;
}