致CSDN的一封信的内容介绍
CSDN编辑,各位网友,以及关注这个博客的全国各族人民:
你们好!十多天没更新博客,是我的失职,我向各位致以最真诚的道歉。
为什么没有更新?你们是不是怀疑,我在外面吃喝拉风?是不是以为,腾讯的面试,把我打击得神经衰弱?
我再次向媒体澄清:绝没有这回事!请大家不要随意猜测,本人对程序的热爱是刚刚地!
这段时间,我没有闲着,请大家相信我。我真的是一个好学的好孩子。为了证明,我不仅好学,而且好思。那么,我举一个例子,首先我问一个问题:
如何判断一个链表是否存在循环?有谁能答出来?
A举手了,我请他来回答。
A说:“用两个指针Pa、Pb,一同指向链表头,然后令Pa的增量为1,令Pb的增量为2,这样放在一个循环体内,每循环一次,就判断*Pa与*Pb是否相等,如果相等,刚表明链表循环,跳出循环体返回true,否则至到Pb为NULL,循环结束返回false,表明链表没有循环”。
答得相当严谨!但是,A同学,请问,你是怎么得出这个方法的?
A回答:“我在百度搜到的啊”^_^
确实是这样的,百度给了我们很多知识,不过,能够满足我们好学的要求,但是,但是但是,思考也同样重要。好,现在我来向大家证明,这种方法的正确性:
要证明这个方法的可行性,本质就是要证明,对于一个存在循环的链表,Pa与Pb必然会相遇。
首先,我来作一个感性的比喻,如果带有循环的链表,是一个环形跑道,见下图A:
现在Pa和Pb从入口起跑,显然,由于Pb的速度是Pa的两倍(因为Pb的增量为2),开始的时候,他会跑在Pa的前头,但进入了跑道环后,由于Pa跑得慢,Pb必然会再次“追上”Pa,从而相遇。
嗯,这样看来,证明也太简单了。但是,如果你觉得这样的证明已经足够,那那那,你做事的严谨性,就让人担心了。
因为指针是跳跃前进的,用一句比如专业的术语,它是离散的。那么,就完全可能出现一种情况:由于Pb每次跳两格,那么,它可能跳过了Pa,从而没有相遇。现在,我就来证明,我换一种思路,用归纳法,证明在循环的链表,这两个指针最终会相遇:
先假设,目前pb所在的位置为pos,而Pa所在的位置为pos+offset(在链表的循环部分,我们可以主观上,想象Pa在Pb的前方,即想象Pb在追Pa)
那么,
1、当offset=0时,即Pa与Pb已经相遇,offset=1时,再经过一次循环,因为Pb跳两格,pa跳一格,会相遇。
2、设offset=k时,Pa与Pb会相遇。这时,Pa与Pb相差的格数为:k(即(pos+k) - pos = k)。那么,当offset=k+1时,此时Pb在pos,而Pa在(pos+k+1),经过一次循环后,Pb在(pos+2)、Pa在(pos+k+1+1),这里,Pa与Pb相差的格数为:k。
3、根据归纳假设,由于offset=k时,会相遇;且offset=k+1时,经过一次循环,offset会变为k,所以也会相遇。从而offset为任意值时,Pb与Pa最终都会相遇。
故得证。
好了,还有挺多有意思的东西,以后再慢慢道来。
本文地址:http://www.45fan.com/dnjc/73716.html