致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最终都会相遇。

  故得证。 

  好了,还有挺多有意思的东西,以后再慢慢道来。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值