• 判断单链表是否有环的两种方法


    如图,如果单链表有环,则在遍历时,在通过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 }
    复制代码
  • 相关阅读:
    AC自动机模板
    2013 ACM/ICPC Asia Regional Changsha Online–C (模拟)
    Codeforces126B
    Codeforces182D
    Codeforces149E
    POJ3080
    POJ2752
    HDU4745
    HDU4737
    POJ1226
  • 原文地址:https://www.cnblogs.com/xingzc/p/5770100.html
Copyright © 2020-2023  润新知