判斷單鏈表是否有環的兩種方法


如圖,如果單鏈表有環,則在遍歷時,在通過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.\n");
33     else
34         printf("method1: has no loop.\n");
35 
36     if (has_loop2(arr[0]))
37         printf("method2: has loop.\n");
38     else
39         printf("method2: has no loop.\n");
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 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM