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

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

8b28580e4017684da6850ed342a5f8d6.png

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

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

代码如下:

18e6ee090c183013a406394273417a9a.png

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 }

a56b8723b14da79e24108c2e456e17a1.png

https://www.cnblogs.com/xingzc/category/864622.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值