两个单链表相交的一系列问题

来源:互联网 发布:wind资讯金融数据终端 编辑:程序博客网 时间:2024/06/01 09:19


//两个单链表相交的一系列问题public class TwoInterList{//链表节点的定义public static class Node{public int value;public Node next;public Node(int data){this.value=data;}}     //返回两个链表相交的第一个节点(只有两种情况(1)两个链表都无环相交 (2)两个链表都有环相交)public static Node getIntersectNode(Node head1,Node head2){if(head1==null||head2==null){return null;}Node loop1=getLoop(head1);Node loop2=getLoop(head2);                //两个都没有环if(loop1==null&&loop2==null){return noLoop(head1,head2);}//两个都有环if(loop1!=null&&loop2!=null){return bothLoop(head1,loop1,head2,loop2);}return null;}//问题一、检验一个链表是否有环,并且返回链表的环的第一个节点public static Node getLoop(Node head){if(head==null||head.next==null||head.next.next==null){return null;}//此种解法只对1->2->3->1情况下成立/**Node p=head;while(p.next!=null){            p=p.next;            if(p==head)            {            return head;            }}*/Node n1=head.next;    // n1->slow  (一步一步走)Node n2=head.next.next; //n2->fast (两步两步走)while(n1!=n2){if(n2.next==null||n2.next.next==null){return null;}n2=n2.next.next;n1=n1.next;}n2=head; //n2 再次指向headwhile(n1!=n2){n1=n1.next;n2=n2.next;}return n1;}   //问题二、检验两个无环链表是否相交,并且返回两个链表相交的第一个节点public static Node noLoop(Node head1,Node head2){           if(head1==null||head2==null)            {            return null;            }            Node cur1=head1;            Node cur2=head2;            int n=0;            while(cur1.next!=null)            {            ++n;            cur1=cur1.next;            }            while(cur2.next!=null)            {            --n;            cur2=cur2.next;            }            //到达最后一个节点如果不相等的话,证明不相交            if(cur1!=cur2)            {                        return null;            }            cur1=n>0?head1:head2; //选取较长的链表            cur2=cur1==head1?head2:head1; //选取较短的链表            n=Math.abs(n);            //较长的链表的链表先走n步            while(n!=0)            {            --n;            cur1=cur1.next;            }            while(cur1!=cur2)            {            cur1=cur1.next;            cur2=cur2.next;            }            return cur1;}//问题三:判断两个有环链表是否相交,相交则返回第一个相交节点public static Node bothLoop(Node head1,Node loop1,Node head2,Node loop2){Node cur1=null;Node cur2=null;if(loop1==loop2){           cur1=head1;           cur2=head2;           int n=0;           while(cur1!=loop1)           {           n++;           cur1=cur1.next;           }            while(cur2!=loop2)           {           n--;           cur2=cur2.next;           }           cur1=n>0?head1:head2;           cur2=cur1==head1?head2:head1;           n=Math.abs(n);           while(n!=0)           {           n--;           cur1=cur1.next;           }           while(cur1!=cur2)           {           cur1=cur1.next;           cur2=cur2.next;           }           return cur1;}else{cur1=loop1.next;while(cur1!=loop1){if(cur1!=loop2){                  return loop1;}cur1=cur1.next;}return null;}}public static void main(String[] args){   //System.out.println("Hello");Node node=new Node(1);node.next=new Node(2);node.next.next=new Node(3);node.next.next.next=node.next;             Node mode=new Node(1);mode.next=new Node(2);mode.next.next=new Node(3);mode.next.next.next=new Node(4);mode.next.next.next.next=mode.next;       System.out.println(getIntersectNode(node,mode).value);}}