链表检测环算法,找到环中的出口节点

链表检测环算法,找到环中的出口节点

  • 如何判断一个链表有环

  方法是使用快慢指针,通过一个slow指针(每次都指向下一个),一个quick指针(每次都指向下面两个)

   因为假设有环的话,quick会追上slow指针

   找到环出口就是通过slow指针指向头节点,quick指针指向之前环的交叉点,然后一直以相同速度(慢指针的速度)

     遍历直到相遇这样找到的就是出口节点

  ps:慢指针遍历速度为每次一个节点,快指针则是遍历两个节点

 

    java实现方法如下

 1  2 
 3 import org.junit.Test;
 4 
 5 public class Main5 {
 6     // node
 7     private static class node {
 8         int val;
 9         node next = null;
10 
11         public node(int a) {
12             this.val = a;
13         }
14     }
15 
16     //
17     public static node create() {
18         // 创建
19         node first = new node(0);
20         node node = first;
21         int i = 1;
22         while (i < 10) {
23             node.next = new node(i);
24             node = node.next;
25             i++;
26         }
27         i = 0;
28         node node2 = first;
29         while (i < 6) {
30             if (i == 5) {
31                 node.next = node2;
32             } else {
33                 node2 = node2.next;
34             }
35             i++;
36         }
37 
38         return first;
39     }
40     //
41     @Test
42     public void test_circle() {
43         node first = create();
44         // 快慢指针方法判断是否为环
45         node quick = first;
46         node slow = first;
47         int i = 0;
48         while (i < 1000) {
49             quick = quick.next.next;
50             slow = slow.next;
51             if (quick == slow) {
52                 System.out.println("这个是一个环");
53                 break;
54             }
55             i++;
56         }
57     }
58     //
59     //主要是通过快慢指针来判断,慢指针从first节点触发,快指针从交叉点出发,最后的交点就是出口节点
60     @Test
61     public void test_getNode() {
62         node first = create();
63         
64         // 快慢指针方法判断是否为环
65         node jiaodian = null;
66         node quick = first;
67         node slow = first;
68         int i = 0;
69         while (i < 1000) {
70             quick = quick.next.next;
71             slow = slow.next;
72             if (quick == slow) {
73                 break;
74             }
75             i++;
76         }
77         //
78         slow = first;
79         while(i<1000) {
80             slow = slow.next;
81             quick = quick.next;
82             if(slow == quick) {
83                 System.out.println("出口节点"+slow.val);
84                 break;
85             }
86         }
87     }
88 }

  

  • 第二个问题就是判断两个链表是否有交点

    判断还是很简单的,只要将两个链表遍历到尾节点,如果尾节点相同,这样就证明这两个链表是有交点的

  如何找到两个链表相交的节点?

  方法:遍历两个链表的长度,然后长链表长度减去短链表长度为K,让长链表减去K,然后两个链表逐个对比

  Java代码

  

 1 @Test
 2     public void test() {
 3         //创建两个链表
 4         node first1 = new node(0);
 5         node node1 = first1;
 6         node first2 = new node(0);
 7         node node2 = first2;
 8         int i=0;
 9         while(i<5) {
10             node1.next = new node(i);
11             i++;
12         }
13         i=0;
14         while(i<5) {
15             node2.next = new node(i);
16             i++;
17         }
18         node ban = new node(6);
19         node node3 = ban;
20         i=0;
21         while(i<5) {
22             node3 = new node(i+5);
23             i++;
24         }
25         node1.next = ban;
26         node2.next = ban;
27         //
28         //这里是判断
29         int length_1 = 0;
30         int length_2 = 0;
31         node1 = first1;
32         node2 = first2;
33         while(node1 != null) {
34             length_1++;
35             node1 = node1.next;
36         }
37         while(node2 != null) {
38             length_2++;
39             node2 = node2.next;
40         }
41         
42         int k = 0;
43         if(length_1>=length_2) {
44             k = length_1-length_2;
45             int j = 0;
46             while(j<k) {
47                 first1 = first1.next;
48                 j++;
49             }
50         }else {
51             k = length_2 - length_1;
52             int j = 0;
53             while(j<k) {
54                 first2 = first2.next;
55                 j++;
56             }
57         }
58         while(true) {
59             if(first1 == first2) {
60                 System.out.println("共同节点"+first1.val);
61                 break;
62             }
63             first1 = first1.next;
64             first2 = first2.next;
65         }
66     }

 

  

 

 

    

 

posted @ 2018-11-02 15:07 肥仔中意编程 阅读(...) 评论(...) 编辑 收藏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值