这个图是两个链表的六种状态第一种是最常见见也是最简单的状态,两个不带环单链表并且两个链表不相交。第二种是两个不带环单链表在半路相交了,之前也写过判断两个链表是否相交的函数,第三种是一个链表带环一个链表不带环,但是两个链表不想交,第四种是两个链表都带环,但是彼此不相交,第五种是一个带环一个不带环,两个相交但是相交位置是在带环链表的环外,第六种就是最复杂的一种,一个链表带环一个不带环,两个链表相交,但是两个链表相交的位置在带环链表的环上。
之前写了判断两个链表是否相交不带环的情况,今天要写的是两个链表相交但是还带环的情况,也就是上图中的五、六中种情况。
void SListIsCycle(SListNode* list)
{
assert(list);
SListNode *fast = list;
SListNode *slow = list;
SListNode *entry=list;
SListNode *meet = NULL;
DataType count = 0;
fast = fast->_next->_next;
slow = slow->_next;
while (fast->_next->_next)
{
if (fast == slow)
{
meet = fast;
printf("链表带环\n");
break;
}
else
{
fast = fast->_next->_next;
slow = slow->_next;
}
}
count++;
slow = slow->_next;
while (meet!= slow)
{
count=count+1;
slow = slow->_next;
}
printf("相遇点的数据为%d\n", meet->_data);
printf("环的长度为%d\n", count);
while (entry == meet)
{
entry = entry->_next;
meet = meet->_next;
}
printf("入口点位置的数据是%d\n", entry->_data);
}
这是之前写的判断链表是否带环的情况,这里判断两链表是否相交的话,首先判断一下,两个链表是否带环,如果两个都带环,那就继续判断两个带环链表是不是相交,无论是上图的第五种情况还是第六种情况,两个链表都是公用同一个链表环,所以。在判断链表是否带环的时候,每个链表都有一个meet指针,这个指针存储了两个链表快慢指针相遇的位置,这时候让其中一个链表的meet值不动,让另外一个链表的meet值每次移动一个值,如果这个移动的指针转了一圈之内遇到了另一个链表的meet指针,那就说明两个链表相交了,如果转了一圈没有遇到那就说明两个链表不想交,所以只要在判断链表是否带环的函数基础上进行一个小小的改动就行。
代码的简单实现,其实实现起来很简单。
void SListCrossNode(SListNode* list1, SListNode* list2)
{
assert(list1 || list2);
SListNode *fast1 = list1;
SListNode *slow1 = list1;
SListNode *fast2 = list2;
SListNode *slow2 = list2;
SListNode *meet1 = NULL;
SListNode *meet2 = NULL;
SListNode *run= NULL;
fast1 = fast1->_next->_next;
slow1 = slow1->_next;
while (fast1->_next->_next)
{
if (fast1 == slow1)
{
meet1 = fast1;
break;
}
else
{
fast1 = fast1->_next->_next;
slow1 = slow1->_next;
}
}
while (fast2->_next->_next)
{
if (fast2 == slow2)
{
meet2 = fast2;
break;
}
else
{
fast2 = fast2->_next->_next;
slow2 = slow2->_next;
}
}
run = meet1;
run = run->_next;
if (run == meet2)
{
printf("两个链表相交\n");
return;
}
while (run != meet1)
{
if (run == meet2)
{
printf("两个链表相交\n");
return;
}
else
{
run = run->_next;
}
}
}
当然,既然有环出现就会有两个快慢指针的相遇点,以及环的入口点,第五种情况的入口点,和求一个链表的时候的情况是相同的。第六种情况则还会出现两个链表的入口点分别来求。