题目:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入 : 1->2->3->4->5->NULL
输出 : 5->4->3->2->1->NULL
#include <algorithm>
#include <unordered_map>
#include <iostream>
#include <vector>
using namespace std;
// 链表结构体
struct node
{
int data;
struct node * next;
node(int _data):data(_data), next(nullptr){}
};
// 创建链表
struct node* init()
{
node* head = new node(1);
node* node1 = new node(2);
node* node2 = new node(3);
node* node3 = new node(4);
node* node4 = new node(5);
head->next = node1;
node1->next = node2;
node2->next = node3;
node3->next = node4;
node4->next = nullptr;
return head;
}
// 方法一:
// 先对原链表做头删操作,再对新链表做头插
node* reverseList(node* head)
{
node *newHead = NULL;
node *curr = NULL;
while (head != NULL)
{
// 对之前的链表做头删
curr = head; // 让curr指针指向传入函数链表的头指针head,两指针指向保持相同
head = head->next; // 然后让head指针指向它的next结点,此时旧链表已经完成了头删操作。
// 对新链表做头插
curr->next = newHead; // 让curr指针的next下一个结点指向新链表的头指针newHead,完成结点的链接,即头插入新的链表中。
newHead = curr; // 然后更新newHead指向为新链表的头结点。
}
return newHead;
}
// 方法二:
node* reverselist(node* head)
{
if (head == NULL)
return NULL;
node* p0 = NULL; // 前指针 p0为NULL
node* p1 = head; // 当前指针 p1为1
node* p2 = head->next; // 后指针 p2为2
// 开始遍历链表,循环判定因子为p1,当它为空时到达链表尾部跳出循环。否则在表中执行循环内逻辑:
while (p1 != NULL)
{
// 将p1指向的当前结点的下一个结点指向p0,即前一个结点。
p1->next = p0; // 此时p0为NULL,那么p1的下一个结点就为空了,它现在是最后一个结点。
// 然后将p0指针指向p1,将p1指针指向p2
// 注意这两步不可以调换顺序,否则正确向后挪移一位。此时完成了三个指针的一轮更迭。
p0 = p1;
p1 = p2; // 此时p0为1,p1为2,p2为3
// 判定p2指针是否为空,如果为空说明此时p2到达了链表结尾,当前指针p1的指向为最后一个结点,它的next即为空。
if (p2 != NULL)
{
p2 = p2->next; // 如果不为空,将p2更新到下一个结点,进行下一次循环。
}
// 下一次进行循环时,就会把截断结点链接到新链表的头部,同时更新三个指针。继续循环。
// 此时p0为2,p1为3,p2为3
}
// 循环终止条件为:p1指向了链表尾部的NULL,此时p1的前指针p0即指向了反转后的链表,它就是新链表的head头指针。此时返回p0即可。
return p0;
}
int main()
{
// 创建链表
node* head = init();
// 反转链表
//head = reverseList(head);
head = reverselist(head);
// 打印链表
while (head != nullptr)
{
cout << head->data << endl;
head = head->next;
}
return 0;
}