C++判断两个链表是否相交算法

1.判断一个链表是否相交,若相交,求交点(假设链表带环)

2.具体思路如下图所示

既然已经分析清楚,那么代码就很好实现了.

Node* IsHaveCrossNode(Node* head1,Node* head2)
    {
        assert(head1);
        assert(head2);
        Node* meetNode1 = IsCircle(head1);
        Node* meetNode2 = IsCircle(head2);
        //排除第1种情况
        if (meetNode1 == NULL || meetNode2 == NULL)
        {
            return NULL;
        }
        //说明两个链表都带环
        //根据相遇点排除第2种情况
        Node* cur1 = meetNode1->_next;
        while (cur1 != meetNode1 && cur1 != meetNode2)
        {
            cur1 = cur1->_next;
        }
        if (cur1 != meetNode2)
        {
            return NULL;
        }
        //区分第3和第4种情况(需要求出两个入口点)
        Node* entry1 = GetEntryNode(head1, meetNode1);
        Node* entry2 = GetEntryNode(head2, meetNode2);
        //第3种情况(转化为求两个链表的交点,链表不带环时)
        if (entry1 == entry2)
        {
            entry1->_next = NULL;
            entry2->_next = NULL;
            Node* meet = IsMeet(head1, head2);
            return meet;
        }
        //第4种情况(有两个入口点,返回一个即可)
        return entry1;
    }
内部调用的函数如下:
   //判断一个链表是否带环
    //思路:快慢指针,返回相遇点
    Node* IsCircle(Node* head)
    {
        if (head == NULL)
        {
            return NULL;
        }
        Node* pFast = head;
        Node* pSlow = head;
        //快指针一次走两步,慢指针一次走一步
        while (pFast && pFast->_next)
        {
            pFast = pFast->_next->_next;
            pSlow = pSlow->_next;
            if (pFast == pSlow)
            {
                break;
            }
        }
        if (pFast && pFast->_next)
        {
            return pFast;
        }
        return NULL;
    }


Node* GetEntryNode(Node* head, Node* meetNode)
    {
        assert(head && meetNode);
        Node* p1 = head;
        Node* p2 = meetNode;
        while (p1 != p2)
        {
            p1 = p1->_next;
            p2 = p2->_next;
        }
        return p1;
    }

//判断是否相交,判断尾节点
    //若相交,则返回交点
    Node* IsMeet(Node* head1,Node* head2)
    {
        assert(head1 && head2);
        Node* cur1 = head1;
        int count1 = 0;
        Node* cur2 = head2;
        int count2 = 0;
        while (cur1->_next)
        {
            ++count1;
            cur1 = cur1->_next;
        }
        while (cur2->_next)
        {
            count2++;
            cur2 = cur2->_next;
        }

        if (cur1 != cur2)
        {
            return NULL;//说明没有交点
        }

        int D_val = count2 - count1;
        if (D_val < 0)
        {
            D_val = -D_val;
        }
        //
        cur1 = head1;
        cur2 = head2;
        if (count1 < count2)
        {
            //让head2链表先走D_val长度
            while (cur2 && D_val--)
            {
                cur2 = cur2->_next;
            }

            while (cur2 && cur1 != cur2)
            {
                cur1 = cur1->_next;
                cur2 = cur2->_next;
            }
            if (cur1 == cur2)
            {
                return cur1;
            }
        }
        else
        {
            //让head1链表先走D_val长度
            while (cur1 && D_val--)
            {
                cur1 = cur1->_next;
            }

            while (cur1 && cur1 != cur2)
            {
                cur1 = cur1->_next;
                cur2 = cur2->_next;
            }
            if (cur1 == cur2)
            {
                return cur1;
            }
        }
        return NULL;
    }

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值