博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
7_2判断两个单链表是否相交,若相交,求出第一个交点
阅读量:6502 次
发布时间:2019-06-24

本文共 5078 字,大约阅读时间需要 16 分钟。

转载请注明出处:

声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明。谢谢。

题目:7_2判断两个单链表是否相交,若相交,求出第一个交点。

题目分析:

  创建A,B两个单链表,将B的尾部指向头部,若两个单链表相交,则交点必为环的入口,这就又变成上边判断一个单链表是否有环的问题了。

  注: 若两个单链表相交,则相交之后的那些节点比都是一样的(相交之后的长度是一样的),否则若一长一短或者相交之后有分叉,则在短链表末尾或者分叉节点处,该节点将有两个next分别指向两边的链表,这就不是单链表了。

   

 

 

源码实现:

1 package com.interview;  2   3 /**  4  * 判断两个单链表是否相交,若相交,求出第一个交点  5  * 方法:创建A,B两个单链表,将B的尾部指向头部,若两个单链表相交,则交点必为环的入口  6  *   若两个单链表相交,则相交之后的那些节点比都是一样的(相交之后的长度是一样的),  7  *   否则若一长一短或者相交之后有分叉,则在锻炼表末尾或者分叉节点处,该节点将有  8  *   两个next分别指向两边的链表,这就不是单链表了  9  * @author wjh 10  * 11  */ 12 public class _7_2JudgeListCross { 13  14     /** 15      * @param args 16      */     17     //分别记录相交前A表的长度,B链表(圈)的长度,第一次相遇时慢指针走的总长度 18     public static int x=0, y=0, k=0;    19     public static void main(String[] args) { 20         //1)创建两个相交的链表 21         Node nodeA = createList("A", 28); 22         Node nodeB = createList("B", 3); 23         Node tail = createTail(3); 24         nodeA = merge(nodeA, tail); 25         nodeB = merge(nodeB, tail);         26         //2)将B的尾节点指向B的第一个节点 ,此时若相交,A的结构就变成带环单链表了, 27             //若不相交则遍历A会走到null 28         Node r = findTail(nodeB);  //若要求A B的长度,则在上面遍历nodeA,nodeA 29         r.next = nodeB.next; 30         judge(nodeA); 31  32     } 33      34      35     //创建带头节点的无环单链表的相较之前的部分 36     public static Node createList(String name, int k){ 37         /**  1)用尾插法构建单链表,此处构建有环单链表,让node24指向node6*/ 38         Node first = new Node(null,null);    //头节点 39         Node r = first;   //指向链表的尾节点 40         for(int i=1;i<=k;i++){  //根据传入参数创建相交之前的部分节点 41             Node node = new Node("猫狗_"+name+"_"+i,null); 42             r.next = node; 43             r = node; 44         } 45         r.next = null;       //若是构建无环单链表,此处   r.next = null; 46         return first; 47     } 48      49     //创建带头节点的无环单链表的相较之后的相同的部分 50     public static Node createTail(int k){ 51         Node first = new Node(null,null);    //头节点 52         Node r = first;   //指向链表的尾节点 53         for(int i=1;i<=k;i++){  //创建相交之后的部分节点 54             Node node = new Node("相同节点@"+i,null); 55             r.next = node; 56             r = node; 57         } 58         r.next = null;       //若是构建无环单链表,此处   r.next = null; 59         return first; 60     } 61      62     //将相交之前和相交之后的链表穿起来 63     public static Node merge(Node first, Node second){ 64         Node r = first;   //记录前面链表的尾部节点 65         while(r.next!=null){ 66             r = r.next; 67         } 68         //因为second是后面链表的头节点,是空的,头节点下一个节点才是真正的节点 69         r.next = second.next; 70         return first; 71     } 72      73     //找到一个链表的尾节点 74     public static Node findTail(Node node){ 75         Node r = node;   //记录前面链表的尾部节点 76         while(r.next!=null){ 77             r = r.next; 78         } 79         return r; 80     } 81  82     //判断是否有环 83     public static void judge(Node first){ 84         /**  2)判断是否有环若pq先重合则有环,若q先指向null,则无环    */ 85         Node p = first.next; 86         Node q = first.next; 87         String flag = "0";  //标记有环还是无环,0-无环,1-有环 88         if(p==null){     //空链表 89             System.out.println("链表为空!"); 90             return; 91         } 92         k=1; 93         while(q.next!=null && q.next.next!=null){ 94             k++;      //记录相遇时p指针走的长度,k从0开始,因为k已经加过1了才判断pq是否相等 95             p=p.next; 96             q=(q.next).next; 97             if(q.equals(p)){ 98                 flag="1"; 99                 System.out.println("p和q相遇了,这两个单链表相交!");100                 break;101             }102         }103         104         /**  3)有环的时候求环的入口节点    */105         if(flag.equals("1")){    //有环106             p=first.next; //p重新指向第一个节点107             searchEnter(p,q);108         }109         else{   //是因为q走到了尽头才跳出循环的,无环110             System.out.println("这两个单链表不相交!");111         }112     }113     114     //求环的入口节点    115     public static void searchEnter(Node p, Node q){116         x=1;117         while(!q.equals(p)){118             x++;  //求圈外长度119             p=p.next;120             q=q.next;121         }122         Node r = q.next;   //为了求圈长设定的123         y = 1;     //求圈长度124         while(r!=q){125             r = r.next;126             y++;127         }128         System.out.println("相交节点是A链表中的第"+ x+"个节点!");129         System.out.println("相交节点的名字为: "+ p.name);130         System.out.println("B链表的长度是:"+ y);131         System.out.println("第一次相遇时,慢指针在B圈内走的长度为:"+ (k-x));132         System.out.println("第一次相遇时,快指针在B圈内走了:"+ (k/y)+"圈");133         System.out.println("第二次相遇时,快指针在B圈内又走了:"+ (k/y-1)+"圈");134     }135     136     137     //创建一个私有的节点类138     private static class Node {139         public String name;140         public Node next;141         public Node(String name, Node next) {142             super();143             this.name = name;144             this.next = next;145         }146     }147 }
View Code

 

运行结果:

1.有交点:

p和q相遇了,这两个单链表相交!

相交节点是A链表中的第29个节点!
相交节点的名字为: 相同节点@1
B链表的长度是:6
第一次相遇时,慢指针在B圈内走的长度为:2
第一次相遇时,快指针在B圈内走了:5圈
第二次相遇时,快指针在B圈内又走了:4圈

 

2.无交点:

这两个单链表不相交!

 

转载于:https://www.cnblogs.com/wuzetiandaren/p/4251372.html

你可能感兴趣的文章
JPA常用注解
查看>>
Java基础学习总结(1)——equals方法
查看>>
Maven学习总结(6)——Maven与Eclipse整合
查看>>
HTML5:理解head
查看>>
oracle
查看>>
java SpringUtil获取bean
查看>>
Centos6.4最小化安装系统初始化脚本
查看>>
PaaS变厚了
查看>>
赛门铁克开启“容灾即服务”时代
查看>>
复杂度归纳--小结
查看>>
PHP学习笔记 第八讲 Mysql.简介和创建新的数据库
查看>>
【git】git入门之把自己的项目上传到github
查看>>
js获取鼠标位置
查看>>
2016.8.11 DataTable合并及排除重复方法
查看>>
php 魔术方法 说明
查看>>
Mysql
查看>>
POJ-1860-Currency Exchange
查看>>
跨越企业的“中等收入陷阱”
查看>>
Android 开发者必知的开发资源
查看>>
软件工程技术基础-(软件复用技术)
查看>>