数学解题(一)单向链表反转
来源:互联网 发布:mysql in 子查询原理 编辑:程序博客网 时间:2024/04/29 06:11
0 如何分析数学问题
大部分问题是数学问题,代码只是表示数学问题的一种有效方式。在遇到一个待解决的问题时,先从数学的角度考虑这个问题,已知条件是什么?给定的已知条件有什么性质可用?处理一般情况的步骤?特殊情况是什么?分析好这些问题,然后在入手写代码。下面以链表反转为例。
面试题:定义一个函数,输入一个单向链表的头节点,反转该链表并输出反转链表的头节点。链表节点定义如下:
Class Link{
int key;
Link next;
}
1 已知条件
已知单链表,那么单链表有哪些性质可用?
性质1:链表是已知头节点的
性质2:单向链表能够从一个节点知道下一个节点,next=current.next (即图中B->C)
性质3:单向链表的尾节点的下个节点是null,更具这个性质我们常常遍历单向链表,结束条件是current==null
2 分析问题
从问题的结果考虑,以上图为例,我们希望反转后链表中
A<-B,
而先前是A->B
所以我们需要在遍历节点的时候保存节点A和B的信息,然后将B->A。 但是B->A后,无法再根据B找到C(因为我们已经将B的下一个节点指向了A),因此,无法再循环遍历下去。所以在改变B->A之前,需要保存B->C的信息。至此,我们需要3个指针指向A,B,C来保存其处理前的信息,如下图(这里用到了性质2和性质3)
现在,我们总结下处理该问题的步骤:
step1: 保存3个节点的信息
previous=current
current=current.next
next=current.next
step2: 节点反转
current.next=previous
current=next
step3: 循环步骤1和2
循环结束条件current==null (性质3)
step4: 循环结束后处理原来的头节点
first.next=null
step5: 返回反转后链表的头节点
即previous,因为循环结束后current为null,则前一个节点previous为反转后的头节点
3 特殊情况
现在我们要返回头看下上述解决问题的步骤,我们发现解决该问题,必须要先满足以下条件:即链表中要存在多于2个节点,才能有3个指针指向A,B,C。
那么根据这个一般情况条件,我们可以得出如下的特殊情况:
1)链表为空
2)链表只有1个节点
3)链表只有2个节点
4 代码实现
4.1 先写出代码框架
在写具体代码写,先写出代码框架,有助于问题的发现和解决,并减少错误
public Link reverseList(LinkedList list, Link firstLink) {// sepecial caseif (list == null)return null;// list have only one nodeif (firstLink.next == null)return firstLink;// initial three pointerLink previous = null;Link current = firstLink;Link next = current.next;// list have only two nodeif (next == null) { //TODO}// end if// list have more than two nodeswhile (current != null) {// step1: keep three pointer// previous=current// current=current.next// next=current.next// step2: reverse// current.next=previous// current=next//TODO}// end while//step4: make first as the last pointer first.next=null firstLink.next=null; //step5: return the firstLike after reverse TODO}// end reverseList
4.2 其次写出代码测试用例
写出测试用例,对后面的代码解析测试
// test case// list is null// list have only one node// list have only two nodes// list have more than two nodes
4.3 最后才是代码具体实现
public Link reverseList(LinkedList list, Link firstLink) {// sepecial caseif (list == null)return null;// list have only one nodeif (firstLink.next == null)return firstLink;// initial three pointerLink previous = null;Link current = firstLink;Link next = current.next;// list have only two nodeif (next == null) { current.next=previous; firstLink.next=null; return current;}// end if// list have more than two nodeswhile (current != null) { //reverse current.next=previous; current=next;// keep three pointer previous=current; current=current.next; next=current.next;}// end while//step4: make first as the last pointer first.next=null firstLink.next=null; //step5: return the firstLike after reversereturn previous;}// end reverseList
4.4 用测试用例对代码进行测试
- 数学解题(一)单向链表反转
- 单向链表反转
- 反转单向链表
- 单向链表反转
- 单向链表反转
- 单向链表反转
- 反转单向链表
- 反转单向链表
- 反转单向链表
- 反转单向链表
- 单向链表反转
- 单向链表反转
- 单向链表反转
- 单向链表反转
- 反转单向链表
- 单向链表反转
- 反转单向链表
- 反转单向链表
- GridView 动态隐藏控件
- eclipse调试java程序的九个技巧
- 类与类之间的关系图(Class Diagram,UML图)
- ubuntu gcc/g++ 设置默认版本
- 鸟哥的Linux私房菜基础学习篇(第三版)之第三章:主机规划与磁盘分区
- 数学解题(一)单向链表反转
- 浅谈数据仓库建设中的数据建模方法
- spring log4j.properties文件内容
- 修改Linux系统下的最大文件描述符限制
- 3DES、AES、RC6、TEA、RSA、MD5、SHA1、SHA256大聚齐
- grunt 0.4.1构建工具入门实践
- hdu_2001_计算两点间的距离_解题报告
- 嵌入式学习
- 为什么说Mac OS X的Dock没有Windows任务栏好用