计算单链表的节点数

给定一个单链表,它可能包含环,也可能不包含环。环可能从节点头开始,也可能不是。计算单链表的节点数。


通过floyd循环检测算法找到环头节点。节点总数为环中的节点数加上不在环中的节点数。

如果链表不包含环,环中的节点数为0.

1.维护两个指针,hare(兔子)和tortoise(乌龟)

2.hare一次移动两步,乌龟一次移动一步,直到两个指针相等,或者hare指针指向NULL。

3.如果两个指向相等,将tortoise指针指向链表头。一步一步移动hare和tortoise指针,二者相等时,指向的节点为环的首节点。计算不在环上的节点个数。(也可以从将tortoise指针指向链表头时开始计算) 然后,从环的首节点开始计算环上节点的个数。


简单证明:

既有环又有非环部分:

假设非环部分长m,相遇点距离环的开始节点为k,环的长度为n,hare和tortoise在 i 时刻相遇,由于hare和tortoise每一时间各走2步和1步。

那么tortoise 走的距离:

i*1 = m+k+p*n。

那么hare走的距离:

i*2 = m+k+q*n

有上面两个式子可以得到:m=(q-2*p)n-k

所以当从相遇点开始,hare走(q-2*p)n距离再回退k个距离 和 tortoise从head开始走m个距离时 即可再次相遇,相遇点在环的首节点。


如果单链表只有环,即环从head开始,hare和tortoise相遇时有   i mod n == 2i mod n  所以i mod n == 0,所以相遇点在head,那么tortoise从head开始,hare从相遇点开始(即head),他们再次相遇时还是在head。也就是环的首节点。


综上,如果有环 hare和tortoise再次相遇一定在环的首节点。

当链表中包含环时,找到相遇的节点

LinkedListNode FindBeginning(LinkedListNode head) {

LinkedListNode n1 = head;

LinkedListNode n2 = head;


// Find meeting point

while (n2.next != null) {

n1 = n1.next;

n2 = n2.next.next;

if (n1 == n2) {

break;

}

}

// Error check - there is no meeting point, and therefore no loop

if (n2.next == null) {

return null;

}

/* Move n1 to Head. Keep n2 at Meeting Point. Each are k steps

/* from the Loop Start. If they move at the same pace, they must

* meet at Loop Start. */

n1 = head;

while (n1 != n2) {

n1 = n1.next;

n2 = n2.next;

}

// Now n2 points to the start of the loop.

return n2;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值