声明:以下内容来自于程序员小熊公众号,仅学习使用,一并感谢。
递归解法
链表具有天然的递归性,一个链表例如:1->2->3->NULL,可以看成以值为1的节点作为头节点后面挂接一个更短的(以值为2的节点为头节点)的链表,即1->更短的链表(以值为2的节点作为头节点),同理以值为2的节点作为头节点后面也挂接一个更更短的链表(以值为3的节点作为头节点);依次类推,如下图示。
有了这样的思考,链表反转就可以先翻转头节点后面挂接的更短的链表,然后再在翻转后的更短链表的后面挂接之前的头节点。具体如下图示:
struct ListNode *reverseList(struct ListNode *head)
{
/* 特判 */
if (head == NULL || head->next == NULL) {
return head;
}
/* 翻转头节点(节点值为1的节点)后面挂接的链表(以节点值为2的节点作为头节点)*/
/* 翻转后变成 3->2 */
struct ListNode* node = reverseList(head->next);
/* 将头节点(节点值为1的节点)挂接在翻转后的链表的后面(也就是节点值为2的节点的后面)*/
head->next->next = head;
/* 将尾节点的下一个节点质空 */
head->next = NULL;
return node;
}
迭代解法
可以用双指针来做,用一个指针next记录当前节点的后一节点,另外一个指针pre记录当前节点的前一个节点,如果当前节点是头节点,则pre为空指针,还是以链表:1->2->3->NULL为栗子,具体如下图示。
struct ListNode* reverseList(struct ListNode* head)
{
/* 记录当前节点的前一个节点 */
struct ListNode* pre = NULL;
while (head != NULL) {
/* 记录当前节点的下一个节点 */
struct ListNode* next = head->next;
/* 翻转当前节点连接前一个节点 */
head->next = pre;
/* 移动指针 */
pre = head;
head = next
}
return pre;
}