【链表】判断两个链表是否相交,并求出交点

来源:互联网 发布:好用的男士爽肤水 知乎 编辑:程序博客网 时间:2024/05/19 07:11

问题描述:判断两个链表是否相交,并求出交点。

简单分析:考虑到链表是否带环的问题,可分为3种情况,

1、两个链表都不带环

2、其中一个链表带环(根本就不可能相交)

3、两个链表带环

下面具体情况具体分析
注:判断链表是否带环,可以查看上一篇博客 判断链表是否带环

1、两个链表都不带环

分析情况:如果两个链表不带环且相交的话,有两种思路:
思路1、 遍历两个链表,如果相加相交的话,最终的结尾点是相等的。但是无法得到相交的点

//方法1:如果两个链表相交的话,最终的节点是相等的bool IsCrossNoCircle1(Node* pHead1, Node* pHead2){    Node* pNode1 = pHead1;    Node* pNode2 = pHead2;    if (pNode1 == NULL || pNode2 == NULL)        return false;    while (pNode1->_next !=NULL && pNode2->_next != NULL)    {        pNode1 = pNode1->_next;        pNode2 = pNode2->_next;    }    if (pNode1 == pNode2)        return true;    return false;}

思路2、求出两个链表的长度L1 L2,然后让长的链表L1先走L1-L2,然后两个链表同时走,相等时即为相遇的点。
返回值即为交点

Node* IsCrossNoCircle(Node* pHead1,Node* pHead2){    //求出链表的长度    int len1 = 1;    Node* p1 = pHead1;    while (p1->_next)    {        ++len1;        p1 = p1->_next;    }    int len2 = 0;    Node* p2 = pHead2;    while (p2)    {        ++len2;        p2 = p2->_next;    }    //求出差值    int step = len1 - len2;    Node* pNode1 = pHead1;    Node* pNode2 = pHead2;    if (step < 0)    {        step = 0 - step;        pNode1 = pHead2;        pNode2 = pHead1;    }    //长的链表,先走step步    for (int i = 0; i < step; ++i)        pNode1 = pNode1->_next;    //两个链表同时走,最后肯定相等NULL或者交点    while (pNode1 != pNode2)    {        pNode1 = pNode1->_next;        pNode2 = pNode2->_next;    }    return pNode1;}

2、链表带环的情况

分析:链表都带环的情况,才可能出现相交的情况,首先判断两个链表是否带环(即可求出链表环中相遇的点MeetNode),遍历其中一个环,看另一个链表中相遇的点是否在同一个环中。

bool IsCrossWithCircle(Node* pHead1, Node* pHead2){    if (pHead1 == NULL || pHead2 == NULL)        return false;    //判断两个链表是否带环    Node* MeetNode1 = IsHaveCircle(pHead1);    Node* MeetNode2 = IsHaveCircle(pHead2);    //都不带环    if (MeetNode1 == NULL && MeetNode2 == NULL)    {        return  IsCrossNoCircle(pHead1, pHead2);    }    //都带环    if (MeetNode1 != NULL && MeetNode2 != NULL)    {        Node * temp = MeetNode1;        //遍历环        while (MeetNode1 != temp->_next)        {            if (temp == MeetNode2)                return true;            temp = temp->_next;        }    }    return false;}

求交点
当带环的链表相交时,分为下面两种情况。

这里写图片描述

对于情况2,根本不存在相交的点;

对于情况1,找到第一个链表的环点,然后将环断开(当然不要忘记了保存它的下一个节点),然后再来遍历第二个链表,如果发现第二个链表从有环变成了无环,那么他们就是相交的嘛,否则就是不相交的了。

在这种情况下,两个链表的交点在环点之前,可以将环点切断,这样就变成了两个无环的链表求相交点,就是方法1。

阅读全文
0 0