链表的反转是一个面试的经典题目,今天做LeetCode题目时,遇到一道题,突然想起,做一下记录。
问题分析:我们知道链表通过头指针以及next指针组成,要做到链表的反转,则需要改变各指针的next指针,使他们指向前面一个指针。即是需要实现如下图的过程,可知,每一次反转指向中会出现两次的“断链”,因为链表之间是通过next指针来联系,“断链”意味着无法找打其他的节点。所以需要额外的辅助指针进行节点的记录。
以p2为例,记录p1为pre,p3为post = p2->next,则可改变p2->next = pre,实现指向的反转。
完整代码如下:
#include <iostream>
#include <string>
using namespace std;
//链表数据结构
struct ListNode{
int val;
ListNode *next;
ListNode(int x=-9999): val(x), next(NULL) {}
};
// 打印链表
void printList(ListNode *rt)
{
ListNode *p = rt;
while(p->next != NULL){
cout <<p->val <<"->";
p = p->next;
}
if(p != NULL) cout <<p->val;
cout <<endl;
}
int main()
{
//测试链表构造,1-9的顺序数字记录
ListNode* root = new ListNode(1);
ListNode* p = root;
for(int i=2;i<10;i++){
p->next = new ListNode(i);
p = p->next;
}
printList(root);
//考虑链表长度大于1,是1则返回,这里不写
ListNode *pre = root;
root = root->next;
ListNode *post = NULL;
pre->next = NULL;
//链表反转
while(root->next != NULL){
post = root->next;
root->next = pre;
pre = root;
root = post;
}
root->next = pre;
printList(root);
return 0;
}
执行结果如下所示:
当然也可以直接开一个vector对链表数据进行记录,然后以空间的代价来实现链表的反转。这个方法空间开销,虽然可以实现,但是不太可取。