反转链表
一、迭代翻转
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
#include <cstddef>
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead==NULL||pHead->next==NULL) return pHead;//若为空链表返回
ListNode *beg, *mid, *end;
beg=NULL, mid = pHead, end = pHead->next;
while(1){
mid->next=beg;//令mid指向与beg相同
if(end==NULL)break;//判断此时end是否为null
//不为null,则整体向后移动三个指针
beg=mid;
mid=end;
end=end->next;
}
pHead=mid;//只改变表头,结束
return pHead;
}
};
二、递归反转
该方法更适用于反转无头结点的链表
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead==NULL||pHead->next==NULL) return pHead;//递归出口
ListNode *new_head = ReverseList(pHead->next);//new_head一直指向最后一个节点
//每跳出一层递归,pHead前移一个,且需改变head->next的指向,同时令head指向NULL。
pHead->next->next=pHead;
pHead->next=NULL;
return new_head;
}
};
三、头插法反转
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead==NULL||pHead->next==NULL) return pHead;//递归出口
ListNode *new_head = NULL;//新建链表
ListNode *tmp;
while (pHead!=NULL) {
tmp=pHead;
pHead=pHead->next;//pHead后移
tmp->next=new_head;//将tmp插入新链表头部
new_head=tmp;//n_h指向新插入的元素
}
return new_head;
}
};
四、就地逆置
与头插法的区别是,头插法是建立了一个新的链表,就地法在原链表改变。
class Solution {
public:
ListNode* ReverseList(ListNode* pHead) {
if(pHead==NULL||pHead->next==NULL) return pHead;//递归出口
ListNode *beg=pHead;
ListNode *end=pHead->next;
while(end!=NULL){
beg->next=end->next;//将end移出链表
end->next=pHead;//end指向表头
pHead=end;//新表头指向end
end=beg->next;//end后移到下个要反转的节点
}
return pHead;
}
};