算法-链表:反转链表
反转一个单链表,要求不能申请额外的内存空间。
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
//方法一:双指针法,定义一个cur指针用于指向头节点,定义一个pre指针初始化为NULL
//首先记录cur->next为tmp,然后依次将cur->next指向pre,pre最终指向头节点
ListNode* reverseList(ListNode* head) {
ListNode *cur = head;
ListNode *pre = nullptr;
ListNode *tmp ;//用于保存cur->next
while (cur != nullptr) {
tmp = cur->next;
cur->next = pre;//反转操作
//更新pre和cur指针
pre = cur;
cur = tmp;//tmp不能释放内存,因为释放内存以后cur指向的内存地址里面没有值了
}
return pre;//pre为头节点
}
//后插入法创建链表
void addNodeEnd(ListNode *head,int val){
ListNode *_dummyHead = new ListNode(0);
_dummyHead->next = head;//虚拟头节点
ListNode *end = new ListNode(val);
ListNode *cur = _dummyHead;
while(cur->next!=nullptr){
cur = cur->next;
}
//当前cur为最后一个节点
cur->next = end;
}
//打印
void printfList(ListNode *head){
ListNode *_dummyHead = new ListNode(0);
_dummyHead->next = head;//虚拟头节点
cout<<"当前链表为:";
ListNode *cur = _dummyHead;//从头节点开始遍历
while (cur->next!=nullptr) {
cout<< cur->next->val<<" ";
cur = cur->next;
}
cout<<endl;
}
int main(){
ListNode *head = new ListNode(7);
addNodeEnd(head,54);
addNodeEnd(head,67);
addNodeEnd(head,2);
addNodeEnd(head,89);
printfList(head);
ListNode *pre = reverseList(head);
printfList(pre);
return 0;
}
//方法二:递归,定义一个cur指针用于指向头节点,定义一个pre指针初始化为NULL
//首先记录cur->next为tmp,然后依次将cur->next指向pre,pre最终指向头节点
ListNode* reverse(ListNode* pre,ListNode* cur){
if(cur == nullptr){
return pre;
}
ListNode *tmp = cur->next;
cur->next = pre;
return reverse(cur, tmp);//这一步其实类同于双指针的写法
}
ListNode* reverseList(ListNode* head) {
return reverse(nullptr, head);
}
输出结果为:
当前链表为:7 54 67 2 89
当前链表为:89 2 67 54 7