反轉鏈表是比較基礎的問題,直接使用暴力法即可,這裏採用了非遞歸和遞歸兩個版本,大家在寫代碼時應該注意要在函數前面檢查指針是否爲NULL的問題,否則很容易會出現空指針的解引用問題:
這裏直接給出代碼,包含測試用例:
//面試題:反轉鏈表
#include <iostream>
using namespace std;
struct ListNode
{
int val;
struct ListNode *next;
ListNode(int x)
:val(x), next(NULL)
{};
};
class Solution
{
public:
//非遞歸
static ListNode* ReverseList(ListNode* pHead)
{
if (pHead == NULL || pHead->next == NULL)
return pHead;
ListNode* pre = NULL;
ListNode* next = NULL;
while (pHead)
{
next = pHead->next;
pHead->next = pre;
pre = pHead;
pHead = next;
}
return pre;
}
//遞歸版本
static ListNode* ReverListR(ListNode* pHead)
{
if (pHead == NULL || pHead->next == NULL)
return pHead;
//找到鏈表中的最後一個不爲NULL的節點
ListNode* newHead = ReverListR(pHead->next);
pHead->next->next = pHead; //讓當前節點的下一個節點的next指針指向當前節點
pHead->next = NULL; //讓當前節點的next指針指向NULL
return newHead;
}
static void PrintList(ListNode* pHead)
{
if (pHead == NULL)
return;
while (pHead)
{
cout << pHead->val << "->";
pHead = pHead->next;
}
cout << "NULL"<<endl;
}
};
void testNR()
{
ListNode l1(1);
ListNode l2(2);
ListNode l3(3);
ListNode l4(4);
ListNode l5(5);
ListNode l6(6);
l1.next = &l2;
l2.next = &l3;
l3.next = &l4;
l4.next = &l5;
l5.next = &l6;
Solution::PrintList(&l1);
ListNode* newHead=Solution::ReverseList(&l1);
Solution::PrintList(newHead);
}
void testR()
{
ListNode l1(1);
ListNode l2(2);
ListNode l3(3);
ListNode l4(4);
ListNode l5(5);
ListNode l6(6);
l1.next = &l2;
l2.next = &l3;
l3.next = &l4;
l4.next = &l5;
l5.next = &l6;
Solution::PrintList(&l1);
ListNode* newHead = Solution::ReverListR(&l1);
Solution::PrintList(newHead);
}
int main()
{
//testNR();
testR();
return 0;
}