左神算法--链表找交点

链表找交点

在这里插入图片描述

首先分有环还是无环

情况一:两个链表都无环

这里又可以分为两种情况,一种是无交点,一种是有交点,这里就看是否两个链表的终点相等,相等就有交点,否则无交点

1、两条单链表没有交点,直接返回NULL就可以
在这里插入图片描述

2、两个链表结尾相等
在这里插入图片描述
这种两个链表分别遍历找到节点数目差值,长的链表先走差值的步数,再两个链表同时走,当两个链表相等的时候就是节点啦

情况二:一个有环一个无环

这种情况是不可能出现交点的,大家可以自己画画看,因此可以直接返回NULL

情况三:两个链表都有环

这里又有三种情况
1、两个链表都有环,但是不相交
在这里插入图片描述
这种就在一个链表的入环口开始往下遍历,如果都再一次到入环口还没找到链表二的入环口,就是这种情况,如果找到了就是2、

2、两个链表都有环,但是进入环的位置不一样
在这里插入图片描述

3、两个链表先相交,再进入环
在这里插入图片描述
这种情况很简单,直接判断两个入环口是否相等就可以

代码

//链表节点
struct node{
    int x;
    node * next;
};
//寻找环,没有就终点节点,有就返回入环节点
node * findloop(node * nodek)
{
    node * fast=new node;
    node * slow=new node;
    fast=nodek;
    slow=nodek;
    while(!(fast->next==NULL||fast->next->next==NULL))
    {
        fast=fast->next->next;
        slow=slow->next;
        if(fast==slow)
        {
            fast=nodek;
            while(fast!=slow)
            {
                fast=fast->next;
                slow=slow->next;
            }
            return fast;
        }
    }
    if(fast->next==NULL)
    return fast;
    else
    return fast->next;

}
node * findcrosspoint( node * nodeone, node * nodetwo)
{
    node *nodeoneloop=new node;
    node *nodetwoloop=new node;
    nodeoneloop=findloop(nodeone);
    nodetwoloop=findloop(nodetwo);

    //一个有环,一个无环
    if((nodeoneloop->next==NULL&&nodetwoloop->next!=NULL)||(nodeoneloop->next!=NULL&&nodetwoloop->next==NULL))
    {
        return NULL;}
    //两个都无环
    if(nodeoneloop->next==NULL&&nodetwoloop->next==NULL)
    {
        //无环无交点
        if(nodetwoloop!=nodeoneloop)
        {
            return NULL;
        }
        //无环有交点
        else{
            node *nodeone1=new node;
            node *nodetwo1=new node;
            nodeone1=nodeone;
            nodetwo1=nodetwo;
            int n=0;
            while(nodeone1!=NULL)
            {
                nodeone1=nodeone1->next;
                n++;
            }
            while(nodetwo1!=NULL)
            {
                nodetwo1=nodetwo1->next;
                n--;
            }
            nodeone1=n>0? nodetwo:nodeone;
            nodetwo1=nodeone1==nodeone ? nodetwo:nodeone;
            n=abs(n);
            while(n)
            {
                nodeone1=nodeone1->next;
                n--;
            }
            while(!(nodeone1==nodetwo1))
            {
                nodetwo1=nodetwo1->next;
                nodeone1=nodeone1->next;
            }
            return nodetwo1;

        }
    }
    //都有环的情况

    if(nodeoneloop!=nodetwoloop)
    {
        node *nodeone1=new node;
        node *nodetwo1=new node;
        nodeone1=nodeoneloop;
        while (nodeone1->next!=nodetwoloop)
        {
            nodeone1=nodeone1->next;
            //都有环但是不相交
            if(nodeone1==nodeoneloop)
            return NULL;
        }
        //都有环且入环点不一样
        return nodeoneloop;
          
    }
    //都有环且在进入环之前相交
    if(nodeoneloop==nodetwoloop)
    {
        node *nodeone1=new node;
        node *nodetwo1=new node;
        nodeone1=nodeone;
        nodetwo1=nodetwo;
        int n=0;
        while(nodeone1!=nodeoneloop)
        {
            nodeone1=nodeone1->next;
            n++;
        }

        while(nodetwo1!=nodeoneloop)
        {
            nodetwo1=nodetwo1->next;
            n--;
        }

        nodeone1=n<0? nodetwo:nodeone;
        nodetwo1=nodeone1==nodeone ? nodetwo:nodeone;
        n=abs(n);
        while(n)
        {
            nodeone1=nodeone1->next;
            n--;
        }
        
        while(!(nodeone1==nodetwo1))
        {
            nodetwo1=nodetwo1->next;
            nodeone1=nodeone1->next;
        }
        // cout<<nodetwo1->x<<endl;
        return nodetwo1;
    }
}

最后,有问题欢迎打扰

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值