zoukankan      html  css  js  c++  java
  • 判断单链表是否有环的两种方法

    如图,如果单链表有环,则在遍历时,在通过6之后,会重新回到3,那么我们可以在遍历时使用两个指针,看两个指针是否相等。


    方法一:使用p、q两个指针,p总是向前走,但q每次都从头开始走,对于每个节点,看p走的步数是否和q一样。如图,当p从6走到3时,用了6步,此时若q从head出发,则只需两步就到3,因而步数不等,出现矛盾,存在环

    方法二:使用p、q两个指针,p每次向前走一步,q每次向前走两步,若在某个时候p == q,则存在环。

    代码如下:

    复制代码
     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 #define LEN 8
     5 typedef struct node* node_t;
     6 
     7 struct node{  
     8     char val;  
     9     struct node *next;  
    10 };  
    11 
    12 //method 1
    13 int has_loop(struct node *head);
    14 //method 2
    15 int has_loop2(node_t head);
    16 
    17 int main()
    18 {
    19     node_t* arr = (node_t*)malloc(sizeof(struct node)*LEN);
    20     arr[0] = (node_t)malloc(sizeof(struct node));
    21     int i;
    22     for(i = 1; i < LEN; i++)
    23     {
    24         arr[i] = (node_t)malloc(sizeof(struct node));
    25         arr[i - 1]->next = arr[i];
    26     }
    27     arr[LEN - 1]->next = NULL;
    28 
    29     //you can add a loop here to test
    30     //arr[6]->next = arr[0];
    31     if (has_loop(arr[0]))
    32         printf("method1: has loop.
    ");
    33     else
    34         printf("method1: has no loop.
    ");
    35 
    36     if (has_loop2(arr[0]))
    37         printf("method2: has loop.
    ");
    38     else
    39         printf("method2: has no loop.
    ");
    40 
    41     return 0;
    42 }
    43 
    44 //if two pointer are equal, but they don't have the same steps, then has a loop
    45 int has_loop(node_t head)  
    46 {  
    47     node_t cur1 = head;  
    48     int pos1 = 0;  
    49     while(cur1){  
    50         node_t cur2 = head;  
    51         int pos2 = 0;  
    52         pos1 ++;  
    53         while(cur2){  
    54             pos2 ++;  
    55             if(cur2 == cur1){  
    56                 if(pos1 == pos2)  
    57                     break;  
    58                 else  
    59                     return 1;
    60             }  
    61             cur2 = cur2->next;  
    62         }  
    63         cur1 = cur1->next;  
    64     }  
    65     return 0;  
    66 } 
    67 
    68 //using step1 and step2 here 
    69 //if exists a loop, then the pointer which use step2 will catch up with the pointer which uses step1
    70 int has_loop2(node_t head)
    71 {
    72     node_t p = head;
    73     node_t q = head;
    74     while (p != NULL && q != NULL)
    75     {
    76         /*
    77         p = p->next;
    78         if (q->next != NULL)
    79             q = q->next->next;
    80         if (p == q)
    81             return 1;
    82             */
    83         //correct it on 17/11/2012
    84         p = p->next;
    85         q = q->next;
    86         if (q != NULL)
    87             q = q->next;
    88         if (p != NULL && p == q)
    89             return 1;
    90     }
    91     return 0;
    92 }
    复制代码
  • 相关阅读:
    CSS盒子模型
    getContextPath、getServletPath、getRequestURI、request.getRealPath的区别
    MYSQL中的CASE WHEN END AS
    单点登录的精华总结
    git&github
    June 21st 2017 Week 25th Wednesday
    June 20th 2017 Week 25th Tuesday
    June 19th 2017 Week 25th Monday
    June 18th 2017 Week 25th Sunday
    June 17th 2017 Week 24th Saturday
  • 原文地址:https://www.cnblogs.com/xingzc/p/5770100.html
Copyright © 2011-2022 走看看