/**
* 问题:有环链表相交问题
* 如何判断两个有环链表是否相交, 相交则返回第一个相交节点, 不相交则返回 null。
*
* 两个链表各自的第一个入环节点, 假设链表1的第一个入环节点记为 loop1,链表 2的第一个
* 入环节点记为 loop2。
*
* 1.如果loop1 == loop2 ,我们只要考虑链表 1从头开始到 loop1这一段与链表 2从头
* 开始到 loop2这一段, 在哪里第一次相交即可, 而不用考虑进环该怎么处理, 这就与单链表
* 相交问题类似, 只不过单链表是把 null作为一个链表的终点, 而这里是把 loop1(loop2)
* 作为链表的终点。但是判断的主要过程是相同的。
*
* 2.如果 loop1 != loop2,让链表 1从loop1出发, 因为loop1和之后的所有节点都在环
* 上, 所以将来一定能回到loop1。如果回到 loop1之前并没有遇到 loop2,说明两个链表 不
* 相交, 直接返回 null; 如果回到 loop1之前遇到了 loop2,说明两个链表相交。因为 loop1
* 和 loop2都在两条链表上,只不过 loop1是离链表1较近的节点,loop2是离链表2较近的节点。
* 所以, 此时返回loop1或loop2都可以。
* @author 雪瞳
*
*/
*代码
public class Node {
public int value;
public Node next;
public Node(int data){
this.value=data;
}
}
public class LoopNode {
Node current1 = null;
Node current2 = null;
public Node loopNode(Node head1,Node head2,Node loop1,Node loop2){
int len1 = 0;
int len2 = 0;
if(loop1 == loop2){
current1 = head1;
while(current1!=loop1){
len1++;
current1=current1.next;
}
current2 = head2;
while(current2!=loop2){
len2++;
current2=current2.next;
}
if(len1>len2){
int pre = len1-len2;
int flag = 0;
current1 = head1;
current2 = head2;
while(current1!=current2){
flag++;
if(flag == pre){
current1=current1.next;
current2=current2.next;
}
current1=current1.next;
}
return current1;
}else if(len2>len1){
int pre = len2-len1;
int flag = 0;
current1 = head1;
current2 = head2;
while(current1!=current2){
flag++;
if(flag == pre){
current1=current1.next;
current2=current2.next;
}
current2=current2.next;
}
return current2;
}else{
return head1;
}
}
int loop = 0;
if(loop1 != loop2){
current1 = loop1.next;
current2 = loop2;
while(current1!=loop1){
if(current1 == current2){
loop =1;
}
current1=current1.next;
}
}
if(loop==0){
return null;
}else{
return loop1;
}
}
}
import java.util.Random;
import java.util.Scanner;
public class TestLoopNode {
private int overTip = 0;
public static void main(String[] args) {
TestLoopNode test = new TestLoopNode();
LoopNode loop = new LoopNode();
Scanner sc = new Scanner(System.in);
Node result = null;
int length1;
System.out.println("请输入环链表长度:...");
length1 = sc.nextInt();
int length2;
System.out.println("请输入环链表长度:...");
length2 = sc.nextInt();
sc.close();
Node head1;
Node head2;
head1=test.getCircleNodeList(length1);
System.out.println("链表初始状态信息:...");
test.showByTip(head1);
head2=test.getCircleNodeList(length2);
System.out.println("链表初始状态信息:...");
test.showByTip(head2);
//result = loop.loopNode(head1, head2, head1.next, head2.next);
//test.showResult(result);
//构造相交链表
Node current1 =head1.next;
while(current1.next!=head1){
current1=current1.next;
}
Node current2 =head2.next;
while(current2.next!=head2){
current2=current2.next;
}
current1.next=head2;
current2.next=head1;
test.setOverTip(10);
test.showByTip(current1);
}
public int getOverTip() {
return overTip;
}
public void setOverTip(int overTip) {
this.overTip = overTip;
}
public void showResult(Node head){
if(head!=null){
System.out.println("环形链表相交,节点的值是:"+head.value);
}else{
System.out.println("环形链表不想交");
}
}
public void showByTip(Node head) {
Node current = null;
int cricleStopTip = 0;
System.out.println("链表内的元素顺序显示如下:...");
current=head;
while(current!=null) {
System.out.print(current.value+" ");
cricleStopTip ++;
current=current.next;
if(cricleStopTip/overTip==2){
System.out.println();
return;
}
}
System.out.println("");
}
public Node getCircleNodeList(int listLength) {
overTip = listLength;
Random rand = new Random();
Node nodeList[]= new Node[listLength];
for(int i=0;i<listLength;i++) {
nodeList[i]= new Node(rand.nextInt(10));
}
for(int i=0;i<listLength-1;i++) {
nodeList[i].next=nodeList[i+1];
}
nodeList[listLength-1].next=nodeList[0];
return nodeList[0];
}
}