每日一题 为了工作 2020 0328 第二十六题

/**
* 问题:链表环问题
* 判断一个链表是否有环, 如果有, 则返回第一个进入环的节点, 没有则返回null。
*
* 分析:
* 如果一个链表没有环, 那么遍历链表一定可以遇到链表的终点: 如果链表有环, 那
*么遍历链表就永远在环里转下去了。如何找到第一个入环节点, 具体过程如下:
*
*1.设置一个慢指针 slow和一个快指针 fast。在开始时,slow和 fast都指向链表的头
*节点 head。然后slow每次移动一步,fast每次移动两步, 在链表中遍历起来。
*
*2.如果链表无环,那么fast指针在移动的过程中一定先遇到终点,一旦 fast到达终点,
*说明链表是没有环的, 直接返回 null,表示该链表无环,当然也没有第一个入环的节点。
*
*3.如果链表有环, 那么 fast指针和 slow指针一定会在环中的某个位置相遇, 当 fast
*和 slow相遇时, fast指针重新回到 head的位置,slow指针不动。接下来 fast指针
*从每次移动两步改为每次移动一步, slow指针依然每次移动一步,然后继续遍历。
*
*4.fast指针和 slow指针一定会再次相遇, 并且在第一个入环的节点处相遇。
*
* @author 雪瞳
*
*/

*代码

public class Node {
	public int value;
	public Node next;
	public Node(int data){
		this.value=data;
	}
}

  

public class LoopNode {

	private Node fast = null;
	private Node slow = null;
	public Node getLoopNode(Node head){
		
		if(head == null || head.next==null||head.next.next==null){
			return null;
		}
		fast = head.next.next;
		slow = head.next;
		//链表是否存在环
		while(fast!=slow){
			if(fast.next==null||fast.next.next==null){
				return null;
			}
			fast =fast.next.next;
			slow =slow.next;
		}
		//链表存在环	
		fast = head;
		while(fast!=slow){
			fast=fast.next;
			slow=slow.next;
		}
		return fast;

	}
	
}

  

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.getNodeList(length1);
		head2=test.getCircleNodeList(length2);
		
		System.out.println("链表初始状态信息:...");
		test.showByTip(head1);
		result = loop.getLoopNode(head1);
		test.showResult(result);
		System.out.println("\n链表初始状态信息:...");
		test.showByTip(head2);
		result = loop.getLoopNode(head2);
		test.showResult(result);
	}
	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+"\t");
			cricleStopTip ++;
			current=current.next;
			if(cricleStopTip/overTip==2){
				System.out.println();
				return;
			}
		}
		System.out.println("");
	}
	public Node getNodeList(int 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];
		}
		return nodeList[0];
	}
	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];
	}
}

  

 

 

posted @ 2020-03-28 13:01  雪瞳  阅读(152)  评论(0编辑  收藏  举报