反转链表
题目描述
输入一个链表,反转链表后,输出新链表的表头。
#include <iostream>
using namespace std;
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {}
};
//第一种方法是:非递归方法
class Solution1 {
public:
ListNode* ReverseList(ListNode* pHead) {
if (pHead == NULL) return NULL;//注意程序鲁棒性
ListNode* pNode = pHead;//当前指针
ListNode* pReverseHead = NULL;//新链表的头指针
ListNode* pPrev = NULL;//当前指针的前一个结点
while (pNode != NULL){//当前结点不为空时才执行
ListNode* pNext = pNode->next;//链断开之前一定要保存断开位置后边的结点
if (pNext == NULL)//当pNext为空时,说明当前结点为尾节点
pReverseHead = pNode;
pNode->next = pPrev;//指针反转
pPrev = pNode;
pNode = pNext;
}
return pReverseHead;
}
};
//第二种方法是:递归方法 /*
class Solution2 {
public:
ListNode* ReverseList(ListNode* pHead) {
//如果链表为空或者链表中只有一个元素
if (pHead == NULL || pHead->next == NULL) return pHead;
//先反转后面的链表,走到链表的末端结点
ListNode* pReverseNode = ReverseList(pHead->next);
//再将当前节点设置为后面节点的后续节点
pHead->next->next = pHead;
pHead->next = NULL;
return pReverseNode;
}
};
/*
递归的方法其实是非常巧的,它利用递归走到链表的末端,然后再更新每一个node的next 值 ,实现链表的反转。而newhead 的值没有发生改变,为该链表的最后一个结点,所以,反转后,我们可以得到新链表的head。
注意关于链表问题的常见注意点的思考:
1、如果输入的头结点是 NULL,或者整个链表只有一个结点的时候
2、链表断裂的考虑
*/
int main()
{
Solution1 *s1 = new Solution1();
Solution2 *s2 = new Solution2();
ListNode *pHead = new ListNode(0);
int i = 5;
while (i)
{
ListNode *p;
p = (ListNode *)malloc(sizeof(ListNode)); //申请新的结点
p->val = i; //结点数据域赋值
p->next = pHead->next; //将结点插入到表头pHead-->|2|-->|1|-->NULL
pHead->next = p;
i--;
}
ListNode* pHead1 = pHead;
ListNode* pHead2 = pHead;
//ListNode* pr = s1->ReverseList(pHead1);
ListNode* pr2 = s2->ReverseList(pHead2);
/*
while (pr->next != NULL)
{
cout << pr->val << endl;
pr = pr->next;
}
*/
while (pr2->next != NULL)
{
cout << pr2->val << endl;
pr2 = pr2->next;
}
return 0;
}