24 反转链表(第3章 高质量的代码-代码的鲁棒性)

题目描述:

输入一个链表,反转链表后,输出新链表的表头。

测试用例:  

 1)功能测试(输入的链表含有多个节点、链表中只有一个节点)

 2)特殊输入测试(链表头节点为nullptr指针)

解题思路:

 1)最普通的方法:定义三个指针,从头节点开始遍历,一点一点反转链表至链表结束。

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(pHead == nullptr)
            return nullptr;
        if(pHead->next == nullptr)
            return pHead;
        
        ListNode* preNode = pHead;
        ListNode* currNode = pHead->next;
        ListNode* tempNode = nullptr;
        
        while(currNode!=nullptr){
            tempNode = currNode->next; //可能会为空
            if(preNode == pHead){
                preNode->next = nullptr;
                currNode->next = preNode;
            }else{
                currNode->next = preNode;
            }
            preNode = currNode;
            currNode = tempNode;
        }
        
        pHead = preNode;
        
        return pHead;
    }
};

2)第一次遍历链表,将链表每个node的值(val)存入栈中。由于栈“后进先出”,再次遍历链表,并从数据中依此读取栈顶元素。注意pop()并不会返回元素,因此应该使用top()访问栈顶元素。  也可以在栈中存储节点 stack<ListNode*> saveNode;

class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(pHead == nullptr) 
            return nullptr;
        if(pHead->next == nullptr) //只有一个节点
            return pHead;
        
        ListNode* currNode = pHead;
        stack<int> saveValued;

        while(currNode!=nullptr){
            saveValued.push(currNode->val);
            currNode = currNode->next;
        }
        
        currNode = pHead;
        while(currNode!=nullptr){
            currNode->val = saveValued.top(); //访问栈顶元素
            saveValued.pop(); //删除栈顶元素,并没有返回值
            currNode = currNode->next;
        }
        
        return pHead;
    }
};

3)用递归实现反转链表:

class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(pHead == nullptr || pHead->next == nullptr) 
            return pHead;

        ListNode* newHead = ReverseList(pHead->next);
        pHead->next->next = pHead;
        pHead->next = nullptr;
        return newHead;
    }
};
/*解析:当递归调用到pHead为最后一个节点时,返回pHead(尾节点)赋值给newHead。
即newHead指向尾节点。结束本次调用。
此时,返回到上一个节点的调用,即pHead为倒数第二个节点,
pHead->next->next = pHead;将其下一个节点的指针指向该节点
pHead->next = nullptr; 删除该节点向下一个节点的指针
直到递归结束,返回新的头节点即可
*/

  

  

原文地址:https://www.cnblogs.com/GuoXinxin/p/10449509.html