剑指Offer(第2版)——面试题24:反转链表

题目:

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。链表节点定义如下:

struct ListNode
{
	int		m_nKey;
	ListNode* m_pNext;
};

1.解题思路:

  • 可以定义三个指针,分别指向当前遍历到的节点、它的前一个节点以及后一个节点。在遍历的时候,替换当前节点的后一个节点和前一个节点即可。
  • 保存前一个节点的原因:需要把当前节点指向前一个节点。
  • 保存后一个节点的原因:当前节点指向前一个节点后,防止链表断开。

2.代码:

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution{
public:
    ListNode* ReverseList(ListNode* pHead){
        //如果链表为空或者链表中只有一个元素
        if(!pHead || !pHead->next) return pHead;
        //定义前一个节点与后一个节点
        ListNode* pPre = nullptr;
        ListNode* pNode = pHead;
        ListNode* pNext = nullptr;
        //反转循环的条件
        while(pNode != nullptr){
            //保存下一个节点的信息,保证单链表不会因为失去当前节点的原next节点而就此断裂
            pNext = pNode->next;
            //如果下一个节点为空,进行最后一次反转,同时可以设置头节点
            if(pNext == nullptr) pHead = pNode;
            //保存后,将当前节点指向前一个节点
            pNode->next = pPre;
            //完成一次反转,使三个指针向后移动一位,继续下轮反转
            pPre = pNode;
            pNode = pNext;
        }
        //反转完毕,返回头节点
        return pHead;
    }
};

递归法:

class Solution{
public:
    ListNode* ReverseList(ListNode* pHead){
        //如果链表为空或者链表中只有一个元素
        if(pHead == nullptr || pHead->next == nullptr) return pHead;
        //走到链表的末端节点,先反转后面的链表
        ListNode* pReverseNode = ReverseList(pHead->next);
        //建立新的反转连接
        pHead->next->next = pHead;
        //断开原来连接
        pHead->next = nullptr;
        //反转完毕
        return pReverseNode;
    }
};

你可能感兴趣的:(剑指Offer(第2版),链表,递归)