如图,如果单链表有环,则在遍历时,在通过6之后,会重新回到3,那么我们可以在遍历时使用两个指针,看两个指针是否相等。
方法一:使用p、q两个指针,p总是向前走,但q每次都从头开始走,对于每个节点,看p走的步数是否和q一样。如图,当p从6走到3时,用了6步,此时若q从head出发,则只需两步就到3,因而步数不等,出现矛盾,存在环
方法二:使用p、q两个指针,p每次向前走一步,q每次向前走两步,若在某个时候p == q,则存在环。
代码如下:
1 #include
2 #include
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 }
https://www.cnblogs.com/xingzc/category/864622.html