【题目13】判断一个链表是否存在环

解题思路: 网上最经典的解法,追击法。设立两个指针,一个指针p加1

一个指针q加2,往链表末端移动。如果q==null,则说明链表没有环,如果

p==q,则说明链表存在环。

 

核心算法:

bool HasCycle(Node* head) { Node* p = head; Node* q = head; while(true) { p = p->next; q = q->next->next; if(q == NULL) return false; if(p == q) return true; } } void AddCycle(Node* head, int n) { Node* p = head; Node* q = head; while(p->next) p = p->next; for(int i = 0; i < n; i++) { if(i == n-1) p->next = q; q = q->next; if(q == NULL) printf("error!/n"); } }

 

测试的代码:

#include <stdio.h> #include <stdlib.h> struct Node { Node* next; int value; }; Node* InsertNode(Node* head,int value) { if(head == NULL) { head = (Node*)malloc(sizeof(Node)); if(head == NULL) printf("malloc failed."); else { head->next = NULL; head->value = value; } } else { Node* cur = (Node*)malloc(sizeof(Node)); if(cur == NULL) printf("malloc failed."); else { cur->next = head; head = cur; cur->value = value; } } return head; } Node* FreeLink(Node* head) { while(head->next) { Node* cur = head->next; free(head); head = cur; } return NULL; } void PrintLink(Node* head) { Node* p=head; while(p->next) { printf("%d ",p->value); p = p->next; } printf("%d/n",p->value); } bool HasCycle(Node* head) { Node* p = head; Node* q = head; while(true) { p = p->next; q = q->next->next; if(q == NULL) return false; if(p == q) return true; } } void AddCycle(Node* head, int n) { Node* p = head; Node* q = head; while(p->next) p = p->next; for(int i = 0; i < n; i++) { if(i == n-1) p->next = q; q = q->next; if(q == NULL) printf("error!/n"); } } int main() { Node* link =NULL; link = InsertNode(link,1); link = InsertNode(link,2); link = InsertNode(link,3); link = InsertNode(link,4); PrintLink(link); if(HasCycle(link)) printf("Have a cycle./n"); else printf("Have not a cycle./n"); AddCycle(link,2); if(HasCycle(link)) printf("Have a cycle./n"); else printf("Have not a cycle./n"); //FreeLink(link); return 0; }

 

2009年9月20号

这道题的解法还可以用来解决另外一个问题: 找出单向链表的中间结点

Node* FindMidNode(Node* head) { if(head == NULL) return NULL; Node* p = head; Node* q = head; while(true) { p = p->next; q = q->next->next; //链表节点个数为奇数个时 if(q && q->next == NULL) return p; //链表节点个数为偶数个时 if(q && q->next->next == NULL) return p; } return NULL; }

你可能感兴趣的:(算法,struct,测试,null)