单链表的环问题以及相交问题

本文介绍了如何判断单链表中是否存在环,并详细解析了如何找出环的入口点及环的长度。此外,还探讨了两个单链表是否相交的问题,包括判断方法和确定交点的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.求单链表是否有环?若有环,求环的入口点以及环的长度。

流程:创建一个有环的单链表——->
这里写图片描述
先判断是否有环:

public boolean isLoop(){
        Entry fast = head;//走得快的结点
        Entry slow = head;//走得慢的结点
        while(fast != null && fast.next != null){
            fast = fast.next.next;//快的两步走
            slow = slow.next;//慢的一步走
            if(fast == slow){//快的和慢的相遇则证明有环
                return true;
            }
        }
        return false;//否则没环
    }

假若此时单链表有环,求环的入口点:

public int getEntryLoop(){
        if(!isLoop()){//为保证稳定性,先判断是否有环
            return -1;
        }
        Entry fast = head;
        Entry slow = head;
        //先找到相遇点
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                break;
            }
        }
        slow = head;//找到相遇点之后使任意一个回到头结点位置
        //使两个节点接着一步一步走直到相等,如图所示,两段距离均为x,此时的结点就是入口点
        while(fast != slow){
            fast = fast.next;
            slow = slow.next;
        }
        return slow.data;
    }

求环的长度:

public int getLengthLoop(){//看图可知环的长度就是相遇后的X加上相遇前的Y
        int len = 0;
        Entry fast = head;
        Entry slow = head;
        boolean tag = false;
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow && tag == true){//第二次相遇
                break;
            }
            if(fast == slow && tag == false){//第一次相遇
                tag = true;
            }
            if(tag = true){
                len++;
            }
        }
        return len;
    }

2.求两个单链表是否相交?若相交,求交点。

这里写图片描述
判断是否相交:

    public boolean isCut(TestLink t1,TestLink t2){
        TestLink.Entry head1 = t1.getHead();
        TestLink.Entry head2 = t2.getHead();
        int len1 = t1.getLength(); 
        int len2 = t2.getLength();
        int my_len = len1-len2;
        if(my_len<0){//寻找最长的单链表,并且使head1指向最长的单链表
            head1 = t2.getHead();
            head2 = t1.getHead();
        }
        for(int i =0;i<my_len;i++){//使最长单链表走到和另外一个单链表同样的位置(如图的起跑线)
            head1 = head1.next;
        }
        //然后同时一步一步走(如图从起跑线同时走)
        while(head1 != null && head2 != null && head1 != head2){
            head1 = head1.next;
            head2 = head2.next;
        }
        //如果有某一处两个节点相同,则相交,否则不相交(寻找是否有如图的交点)
        if(head1 == head2 && head1 != null && head2 != null){
            return true;
        }else{
            return false;
        }
    }

求交点:

    public int cutPoint(TestLink t1,TestLink t2){
        TestLink.Entry head1 = t1.getHead();
        TestLink.Entry head2 = t2.getHead();
        int len1 = t1.getLength(); 
        int len2 = t2.getLength();
        int my_len = len1-len2;
        if(my_len<0){//使head1指向最长的单链表
            head1 = t2.getHead();
            head2 = t1.getHead();
        }
        for(int i =0;i<my_len;i++){//使最长单链表走到和另外一个单链表同样的位置
            head1 = head1.next;
        }
        //然后同时一步一步走
        while(head1 != null && head2 != null && head1 != head2){
            head1 = head1.next;
            head2 = head2.next;
        }
        //如果有某一处两个节点相同,则相交,则输出值就是交点的值
        if(head1 == head2 && head1 != null && head2 != null){
            return head1.data;
        }else{
            return -1;
        }
    }

求交点值只是在判断有相交之后加上输出就实现了!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值