1 迭代法
迭代法就是一次走到底,是自顶向下的处理方法。
从head开始,一直走到最后。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head)
{
if (head == NULL) {
return NULL;
}
struct ListNode* pre = head;
struct ListNode* cur = head->next;
struct ListNode* temp = NULL;
while (cur != NULL) {
// temp记录的是cur的next指针,这个很重要
temp = cur->next;
// 拆除原有的指向关系
cur->next = pre;
// pre和cur后移
pre = cur;
cur = temp;
}
// 最后记得head->next要置空
head->next = NULL;
return pre;
}
2 递归法
2.1 思路讲解
我们看看递归实现链表翻转的实现,它先循环找到最后面指向的数5,然后从5开始处理依次翻转整个链表。
首先指针H迭代到底如下图所示,并且设置一个新的指针作为翻转后的链表的头。由于整个链表翻转之后的头就是最后一个数,所以整个过程NewH指针一直指向存放5的地址空间。
然后H指针逐层返回的时候依次做下图的处理,将H指向的地址赋值给H->next->next指针
继续返回操作:
上图第一次如果没有将存放4空间的next指针赋值指向NULL,第二次H->next->next=H,就会将存放5的地址空间覆盖为3,这样链表一切都大乱了。接着逐层返回下去,直到对存放1的地址空间处理。
返回到头:
2.2 代码实现
递归法是自底向上的解决问题的办法。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head)
{
// head要放前面,否则head为空的话会有语法问题
if (head == NULL || head->next == NULL) {
return head;
}
struct ListNode* nextNode = head->next;
// newhead的意义在于记录返回值,在后续的处理中并没有用到head
struct ListNode* newhead = reverseList(nextNode);
nextNode->next = head;
// 每次都要置空,否则的话,否则3->next->next = 3;也就是把5的值被3给覆盖掉了,链表会大乱
head->next = NULL;
return newhead;
}
参考链接;
https://blog.youkuaiyun.com/FX677588/article/details/72357389