例一:链表反转
前言:
- 如果链表有100万个元素,资源开销并不大,把它反转也不是见特别复杂的事,
- 但是用“递归”就会调100万次,系统开销非常大,
- 所以要用循环的方法做出链表的反转。
用循环的方法做“链表反转”的步骤:
①定义循环不变式
- 说一句断言,让它在整个循环中始终成立
之前的“递归”做法:
- 把第一个元素单独拿出来,把2345进行递归
“循环”做法:
- 在中间切一刀:
- 前三个结点反转完:
3和4的连接线属于结点3的部分:
切之前,3的next指向4
切之后,3的next指向2
各放一个变量来维持3和4这两个结点:
newHead:新的链表头
【以上是循环不定式】
保证这句话从循环开始到循环结束,
在每次的循环体中,
都要成立。
用循环的方法做“链表反转”的步骤:
①定义循环不变式
②把newHead和currentHead向前推进1
newHead更新为结点4:4321是一个已经反转的链表
currentHead更新为结点5:5指向null没有反转
newHead和currentHead的初始值是?
当什么都没有动的时候,newHead和currentHead仍然要保持【循环不变式】
12345null:往右方向的链表。
- newHead必须指向已经反转成功的链表的头(此时什么都没有反转,已经完成反转的链表是个空链表),newHead指向null;
- currentHead必须指向还没有反转的链表的头(此时什么都没有反转),currentHead指向1;
【如下】
【一步一步个向右推进】
一直推进到:
newHead指向5,currentHead指向null;
此时newHead就是我们要的结果,
54321已经成功把链表进行反转。
用具体代码实现这个想法:
- 在循环之前,假设newHead指向反转成功的链表;
- 当循环体做完之后,保持newHead指向反转成功的链表;
- 通过这4行代码,维持了【循环不变式】,并且把【循环不变式】向前推进了。
在循环体,正确工作
验证循环正确性:
curHead being last node|
next = null
curHead next reversed
newHead points to last node
curHead = null
下一轮循环:curHead != null,跳出循环
输出结果:
结论:
能写循环还是写循环,
虽然写起来可能会比递归难一点点。
完整代码在这里哦!
CheeseCheese-IScream
给个小星星鼓励一下吧~❤谢谢❤