编程思想(技巧)---循环控制
来源:互联网 发布:python 加减法 编辑:程序博客网 时间:2024/06/11 11:31
上一节说了递归控制,最后分析了递归函数的缺点,我们现在使用循环控制将递归函数进行改造,使stack的压力减小,提高程序的运行效率。
循环控制要点:
1.循环不变式(loop invariant)
循环不变式是一句断言定义各变量所需满足的条件,在写循环控制的时候需要重点思考,这么说太抽象,具体看后面例题~
2.循环书写方法:
- 定义循环不变式,并在循环体每次结束后保持循环不变式
- 先一般,后特殊
- 每次必须向前推进循环不变式中涉及的变量值
- 每次推进的规模必须为1
- 编写时假设已经循环了很多次,思考下一次该怎么循环,而不是思考第一次应该怎么循环
3.技巧:
把问题切开,假设一部分已经完成,一部分未完成,思考下一步如何往前推进。
例子1:链表反转
上节中的链表反转使用递归实现,假设链表有一万活着更多元素,运行起来效率极低,而且还有stackoverflow的问题,使用循环实现,效率很高。
思路分析如图:
我们将链表逻辑分开,假设链表左边已经完成了反转,右边没有完成反转,那么只需要思考下一步我怎么把值为3的这个节点反转,我们只需要将currentHead节点指向newHead节点,并将currentHead节点和newHead向后移动即可。完成后,在判断一些边界条件,在while循环中思考如何去除边界条件和退出循环。
我们具体看代码分析:
public class LinkedListReverser { public Node reverseLinkedList(Node head){ Node newHead = null; Node curHead = head; //loop invariant //newHead points to the linked list already reversed //curHead points to the linked list not yet reversed while (curHead!=null){ //loop invariant holds. Node next = curHead.getNext(); curHead.setNext(newHead); newHead = curHead; curHead = next; } //loop invariant holds. return newHead; }}
例子2:删除链表中的某个元素
题目如图:
我们现在要把链表中的节点值为2的节点删除,思路不变,首先假设左边某部分的链表意见删除完毕(比如3节点旁边的2),下面思考如何删除右边部分的节点,我们首先需要判断3右边的节点是否为2,若是,则将指针指向下一个节点,这样就实现了删除该节点,如果3右边节点不是2,next直接指向右边的节点即可。需要思考的是一些边界条件,比如链表为空,或者链表第一个节点就为要删除的元素等等,使用while、if循环处理边界情况。
代码实现如下:
public class LinkedListDeletor { public Node deleteIfEquals(Node head,int value){ while (head.getValue()==value){ head = head.getNext(); } if (head==null){ return null; } Node prev = head; //loop invariant:list nodes from head up to prev has been //processed.(Nodes with values equals to value are deleted) while (prev.getNext()!=null) { if (prev.getNext().getValue()==value){ //delete it prev.setNext(prev.getNext().getNext()); }else { prev = prev.getNext(); } } return head; }}
只要明确了循环不变式,了解了边界条件,写一个循环控制的程序也就不难了,而且循环控制有很多好处,但是循环函数也不是万能的,很多问题无法解决,需要我们具体问题具体分析。下一节是一些关于边界控制的考虑问题。
ps:本打算每天(至少2天)就更新的,结果实验室来个个临时项目,估计要花点时间了~
- 编程思想(技巧)---循环控制
- 编程思想(技巧)---递归控制
- 编程思想-访问权限控制
- shell 脚本编程学习(三) 条件控制,循环控制
- 【Java编程思想--学习笔记(一)】访问控制-包
- 《JAVA编程思想》日志(四)------控制执行流程
- 《JAVA编程思想》日志(六)---------访问权限控制
- java编程思想学习笔记(4)--控制执行流程
- java编程思想---第四章(控制执行流程)
- 【c++编程思想】第十章 名字控制
- java编程思想_001访问控制
- java编程思想访问控制权限总结
- 【Java编程思想】(2)访问权限控制
- JAVA编程思想-访问权限控制
- java编程思想--访问控制权限
- 4控制执行流程-Java编程思想
- 6访问控制权限-Java编程思想
- 《java编程思想》--访问权限控制
- sklean 数据集特征提取
- java学习笔记(一)程序基本结构
- Android -- Activity启动流程分析
- XSS漏洞分析
- springmvc学习2 dispatcherservlet 中初始化策略
- 编程思想(技巧)---循环控制
- Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring(转载-大新博客 -)
- 几种进程间的通信方式
- List Of CAM References LinuxCNCKnowledgeBase
- 电商笔记-02
- 数据结构——顺序表的几个重要方法的C语言实现
- php 实现快速排序算法
- SQL Server读提交快照隔离级别的注意事项
- 深入char*,char**,char a[],char *a[]