zoukankan      html  css  js  c++  java
  • 每日一题 为了工作 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("
    链表初始状态信息:...");
    		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+"	");
    			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];
    	}
    }
    

      

  • 相关阅读:
    【转】Android实战技巧:ViewStub的应用
    3.11 返回数据到前一个Activity
    在用android日志的时候老是弹出一个窗口,内容为:"Copy" did not complete normally. Please see the log 和 什么函数,能达到和android手机上按“返回”键一样的效果?
    Windows下的Android模拟器设置内存大小
    AlertDialog.Builder对话框类的用法(二)
    android版计算器
    【转】Android中字符串的拆分split
    readelf
    6200 uboot 测试版分析(二)
    cpp
  • 原文地址:https://www.cnblogs.com/walxt/p/12586878.html
Copyright © 2011-2022 走看看