判断单向链表是否为环链表,若是,计算环长及入环节点

有一个单向链表,链表中有可能出现“环”,如何用程序判断该链表是否为环链表?
如果是环链表,如果链表有环,计算环的长度以及入环节点。

假设本次环链表如下:

5->3->7->2->6
           |    |
          1<-8

思路:

1. 如何用程序判断该链表是否为环链表?

  创建两个指针p1,p2(节点对象)指向链表头节点,然后p1每次向后移动1个节点,p2每次移动2个节点,然后比较p1和p2是否相同。如果相同,则链表是环链表。

2.如何计算环的长度以及入环节点?

  1. 创建一个map对象,先将head节点(data值)加入到map中;
  2. 然后将每个节点的next节点(data值)添加到一个map对象中;
  3. 每次往map中添加节点时,先判断map的key是否已经存在这个节点的next节点:
    1. 不存在,则加入:map的key=节点的data,map的value为一个自增的int值(可以认为是节点在map中的位置索引值);
    2. 存在,则找到了入环位置了: 入环节点=当前节点的next节点,环长度=(当前节点的索引值-next节点的索引值+1)。


代码实现如下:

 1 public class IsCycleList {
 2     /**
 3      * 构建节点
 4      */
 5     private static class Node{
 6         int data;
 7         Node next;
 8         Node (int data){
 9             this.data = data;
10         }
11     }
12 
13     /**
14      * p1每次向后移动1个节点,p2向后移动2个节点
15      * @param head
16      * @return
17      */
18     public static boolean isCycle(Node head){
19         Node p1 = head;
20         Node p2 = head;
21         while (p2 != null && p2.next != null){
22             p1 = p1.next;
23             System.out.print("p1: " +  p1.data +", ");
24             p2 = p2.next.next;
25             System.out.println("p2: " +  p2.data);
26             if (p1 == p2){
27                 return true;
28             }
29         }
30         return false;
31     }
32 
33     /**
34      * 如果链表有环,计算环的长度以及入环节点
35      * @param head
36      * @return
37      */
38     public static Map<String,Object> cycleLength(Node head){
39         Map<String,Object> resultMap = new HashMap<>();
40         Node p = head;
41         Map<Integer,Integer> indexMap = new HashMap();
42         int i = 0;
43         indexMap.put(p.data,i++);
44         while(p.next != null){
45             if (indexMap.get(p.data) != null && indexMap.get(p.next.data) != null){
46                 int end = indexMap.get(p.data);
47                 int begin = indexMap.get(p.next.data);
48                 resultMap.put("length",end-begin + 1);
49                 resultMap.put("enterNode",p.next.data);
50                 return resultMap;
51             }
52             p = p.next;
53             indexMap.put(p.data,i++);
54         }
55         return resultMap;
56     }
57 
58     public static void main (String[] args){
59         Node node1 = new Node(5);
60         Node node2 = new Node(3);
61         Node node3 = new Node(7);
62         Node node4 = new Node(2);
63         Node node5 = new Node(6);
64         Node node6 = new Node(8);
65         Node node7 = new Node(1);
66         node1.next = node2;
67         node2.next = node3;
68         node3.next = node4;
69         node4.next = node5;
70         node5.next = node6;
71         node6.next = node7;
72         node7.next = node4;  //
73 boolean result = isCycle(node1);
74 System.out.println("========"); 75 System.out.println("Is Cycle: " + result);
76 if(result){ 77 Map<String,Object> resultMap = cycleLength(node1); 78 System.out.println("Cycle Length is: " + resultMap.get("length")); 79 System.out.println("Cycle Enter Node is: " + resultMap.get("enterNode")); 80 } 81 } 82 83 }

结果:

p1: 3, p2: 7
p1: 7, p2: 6
p1: 2, p2: 1
p1: 6, p2: 6
========
Is Cycle: true
Cycle Length is: 4
Cycle Enter Node is: 2


 

猜你喜欢

转载自www.cnblogs.com/zldmy/p/11484877.html