1.判断单链表是否带环?若带环,求环的长度?求环的入口点?
int IsCycle(Node* p)
{
Node* slow, *fast;
fast = slow = p;
slow = slow->next;
fast = fast->next->next;
while ((fast != NULL) ||(fast->nest != NULL))
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
return 1; // 有环
}
}
return 0; // 无环
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
把上面返回的fast的值传给equal
int CycleLength (Node* equal)
{
Node* length = equal;
int count = 1;
length = length->next;
while (length != equal)
{
length = length->next;
count++;
}
return count;
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
如图所示 :假设 链表从开始到 环入口点的距离为a, 从环入口点到fast指针和slow指针相交的地方长度记做c, 环的长度记做b。
可以得到 : 2(a+c) = a+nb+c 2倍的慢指针等于快指针。所以 a+c = nb , a = nb-c;所以只要环上某点满足a = nb-c, 那它就是入口点。
Node* Enter(Node* p, Node* meet)
{
assert(p);
assert(meet);
Node* cur1 = p;
Node* cur2 = meet;
while (cur1 != cur2)
{
cur1 = cur1->next;
cur2 = cur2->next;
if (cur1 == cur2)
{
return cur1;
}
}
assert(false);
return NULL;
}
2.判断两个链表是否相交,若相交,求交点。(假设链表不带环)
Node* MeetNode(Node* p1, Node* p2)
{
assert(p1 && p2);
int len1, len2;
while (p1)
{
len1++;
p1 = p1->next;
}
while (p2)
{
len2++;
p2 = p2->next;
}
int longlist = p1;
int shortlist = p2;
if (len1 < len2)
{
longlist = p2;
shortlist = p1;
}
int gap = abs(len1 - len2);
while (gap--)
{
longlist = longlist->next;
}
while (longlist != shortlist)
{
longlist = longlist->next;
shotrlist = shortlist->next;
}
return longlist;
}
3.判断两个链表是否相交,若相交,求交点。(假设链表可能带环)【升级版】
分情况讨论
第一种情况 ,一条有环,一条无环。这种情况必不可能相交
两个指针,一个快一个慢,一起走。先走第一个链表:快慢指针永远不会相等。再走第二个指针:fast == slow 所有判断出一条链表有环一条链表无环,所以符合第一种情况则 无交点 return NULL;
第二种情况,这种虽然有环,但是也没相交
同一样, fast 指针和slow指针一起走, 则会返回两个不同的 Node * meet , 两个不同的相交点 , 则依旧不想交。
第三种情况 有环相交,可以套用上面的方法
先第一种方法:知道两个链表的头结点,用一个链表的头结点,将其转化为求一条循环链表的进入处,求得Node* meet处后再求Node* Enter处。
让两个链表一起走,判断的条件是(PHead1->next != Enter) 和(PHead2->next != Enter)。
然后比较两个链表走的步数,再让longlist走(longlist- shortlist)步,当longlist与shortlist相等时,返回longlist或者shortlist就是所求的交点。
两链共用一环
此时两个链表共用一个环,故其有两个入口点,随便选择一个输出就是其交点。两个入口点求解方法与上面的相同,fast与slow指针先求meetlist点,再根据结论2(a+c) = a+nb+c,就可求出交点。