翻转链表,并不是创建新的链表结点然后在原链表上实现翻转!这一点一定要注意!
其实是修改原链表的指针,反过来指,就可以达到翻转链表的作用。见下图:
![](https://img-blog.csdnimg.cn/e3c14da92beb41599a08094442060730.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5ZKW5ZWh5b6u6YeP77iP,size_20,color_FFFFFF,t_70,g_se,x_16)
实现链表翻转有两个方法:1.迭代法;2.递归法。今天说一下第1种:迭代法
该方法是利用一个pre结点记录前驱结点,向下枚举,然后改变指针指向就可以。实现代码:
1. 链表的数据结构(C++):
struct ListNode
{
int val; //结点存的数据值
ListNode *next; //结点指针域
ListNode(int x) : val(x), next(NULL) {}
};
2. Solution:
class Solution{
public ListNode reverseList(ListNode head)
{
if(head == null || head.next == null)
return head; //如果结点为NULL或单个结点就直接返回
ListNode pre = head; //将pre指向头结点head
ListNode cur = head->next; //将cur作为head结点的指针域指向的下一个结点
while(cur != null)
{
ListNode next = cur->next; //将next作为cur结点的指针域指向的下一个结点循环
cur->next = pre; //改变cur的指向,即反过来指
pre = cur; //用pre表示cur 即pre下移一位
cur = next; //用cur表示next 即cur下移一位
} //循环 一直到cur指到最后 空为止
head->next = null; //将原先结点的next置null防止最后成环
ruturn pre;
}
}
以上给的是一个Solution,不是可编译运行的代码。基本将算法和注释写明,或许很多朋友阅读还是觉得难以理解,下面我们附上图:
1. 初始化:设5个结点 val = 1, 2, 3, 4, 5
![](https://img-blog.csdnimg.cn/279b8200ef1a4d29a232d156ea1ce5cc.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5ZKW5ZWh5b6u6YeP77iP,size_20,color_FFFFFF,t_70,g_se,x_16)
2. 循环体
1) 第一次迭代
![](https://img-blog.csdnimg.cn/d4a4705db93a4135a2a04873159abbff.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5ZKW5ZWh5b6u6YeP77iP,size_20,color_FFFFFF,t_70,g_se,x_16)
2) 第2次迭代
![](https://img-blog.csdnimg.cn/027d1168f6be4123b4cde8a2ac8cef3d.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5ZKW5ZWh5b6u6YeP77iP,size_20,color_FFFFFF,t_70,g_se,x_16)
3)第3次迭代
![](https://img-blog.csdnimg.cn/97e99739829849189b52507297491d09.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5ZKW5ZWh5b6u6YeP77iP,size_20,color_FFFFFF,t_70,g_se,x_16)
4) 第4次迭代
![](https://img-blog.csdnimg.cn/e0cadbc5429046dda2b34d26b2e477fb.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5ZKW5ZWh5b6u6YeP77iP,size_20,color_FFFFFF,t_70,g_se,x_16)
第4次迭代之后,按照循环体第1步,next = cur-> next 此时next为空(null);第2步cur继续返指pre(即4号结点);第3步用pre表示cur(即结点5);第4步用cur表示next, 而此时next为null,所以 cur == null 退出循环体。
3. 修改head
最后一步修改head的指针域为null。翻转链表完成!
![](https://img-blog.csdnimg.cn/9265d0e5147c43cc904ab6b8dea52c41.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5ZKW5ZWh5b6u6YeP77iP,size_20,color_FFFFFF,t_70,g_se,x_16)
最后再看一下图形:
![](https://img-blog.csdnimg.cn/b597910408ee4dbda94dd723ca26fd25.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5ZKW5ZWh5b6u6YeP77iP,size_20,color_FFFFFF,t_70,g_se,x_16)
这是正规图形,但是容易引起误解,所以都改成上图。记得做任何事情都要懂得分解,罗马不是一天建成的!
![](https://img-blog.csdnimg.cn/264e4a3d4e7a4bb4beaa7ed358c031e1.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5ZKW5ZWh5b6u6YeP77iP,size_17,color_FFFFFF,t_70,g_se,x_16)