源地址:http://blog.csdn.net/yff1030/article/details/8587217
原文链接:http://www.cppblog.com/zengwei0771/articles/172700.html
题目描述:判断两个单链表是否相交,如果相交,给出相交的第一个点(链表中可能有环的情况下)
这里是①判断单链表是否有环,并求出环的入口点;②判断两个链表是否相交(链表中无环),并求出相交节点 的文章
http://www.cppblog.com/humanchao/archive/2008/04/17/47357.html
分析:
①:判断链表1是否有环,并记录其长度L1,尾节点b1(无环),环入口点a1(有环)
②:判断链表2是否有环,并记录其长度L2,尾节点b2(无环),环入口点a2(有环)
③:若一个有环,另一个没环,则判断不相交,结束
④:若两个都没环,则两个尾节点一点是一样的,所以比较两个尾节点是否相同。若不相同则判断不相交,结束;若相同,则到⑥。
⑤:若两个都有环,有如下图三种情况:a1与a2不相等,且不在一个环中,则不相交,结束;a1等于a2,跳到⑥;a1与a2不相等,但在一个环中,对于链表1来说a1是它的相交首节点,对于链表2来说a2是它的相交首节点。
⑥:对于两个链表重头开始遍历,长链表节点先出发前进(Max(L1,L2)-Min(L1,L2))步,之后两个链表同时前进,每次一步,相遇的第一点即为两个链表相交的第一个点。
代码如下:
- typedef struct Node
- {
- int value;
- Node* pNext;
- }* List;
- Node* IsListCross(List L1, List L2)
- {
- if (L1 == NULL || L2 == NULL)
- {
- return NULL;
- }
- int len1 = 0; //L1的长度
- int len2 = 0; //L2的长度
- bool L1HasLoop = false; //L1是否有环
- bool L2HasLoop = false; //L2是否有环
- Node *crossEntry1 = NULL, *crossEntry2 = NULL, *end1 = NULL, *end2 = NULL;
- Node *pNode1, *pNode2, *pNode3; //临时节点指针
- //①
- pNode1 = L1;
- pNode2 = L1;
- while (pNode2 && pNode2->pNext)
- {
- len1++;
- pNode1 = pNode1->pNext;
- pNode2 = pNode2->pNext->pNext;
- if (pNode1 == pNode2)
- {
- L1HasLoop = true;
- break;
- }
- }
- if (L1HasLoop)
- {
- pNode2 = L1;
- while (pNode1 != pNode2)
- {
- len1++;
- pNode1 = pNode1->pNext;
- pNode2 = pNode2->pNext;
- }
- crossEntry1 = pNode1;
- }
- else
- {
- pNode3 = pNode1;
- while (pNode3->pNext)
- {
- len1++;
- pNode3 = pNode3->pNext;
- }
- end1 = pNode3;
- len1++;
- }
- //②
- pNode1 = L2;
- pNode2 = L2;
- while (pNode2 && pNode2->pNext)
- {
- len2++;
- pNode1 = pNode1->pNext;
- pNode2 = pNode2->pNext->pNext;
- if (pNode1 == pNode2)
- {
- L2HasLoop = true;
- break;
- }
- }
- if (L2HasLoop)
- {
- pNode2 = L2;
- while (pNode1 != pNode2)
- {
- len2++;
- pNode1 = pNode1->pNext;
- pNode2 = pNode2->pNext;
- }
- crossEntry2 = pNode1;
- }
- else
- {
- pNode3 = pNode1;
- while (pNode3->pNext)
- {
- len2++;
- pNode3 = pNode3->pNext;
- }
- end2 = pNode3;
- len2++;
- }
- //③
- if (L1HasLoop != L2HasLoop)
- {
- return NULL;
- }
- //④
- else if (L1HasLoop == false)
- {
- if (end1 != end2)
- {
- return NULL;
- }
- }
- //⑤
- else
- {
- //a1 != a2
- if (crossEntry1 != crossEntry2)
- {
- bool onOneLoop = false;
- pNode1 = crossEntry1->pNext;
- while (crossEntry1 != pNode1)
- {
- if (pNode1 == crossEntry2)
- {
- onOneLoop = true;
- break;
- }
- pNode1 = pNode1->pNext;
- }
- //a1 != a2,且不在一个环中
- if (!onOneLoop)
- {
- return NULL;
- }
- //a1 != a2,在一个环中
- else
- {
- return crossEntry1;
- }
- }
- }
- //⑥
- pNode1 = L1;
- pNode2 = L2;
- int gap;
- if (len1 > len2)
- {
- gap = len1 - len2;
- while (gap)
- {
- pNode1 = pNode1->pNext;
- gap--;
- }
- }
- else
- {
- gap = len2 - len1;
- while (gap)
- {
- pNode2 = pNode2->pNext;
- gap--;
- }
- }
- while (pNode1 != pNode2)
- {
- pNode1 = pNode1->pNext;
- pNode2 = pNode2->pNext;
- }
- return pNode1;
- }