#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#define INSERT_NUM 100
#define FAST_POINT_STEP 2
typedef int ElemType;
typedef struct LNode{
ElemType data;
struct LNode *next;
}LinkList, *pNode;
//init the linklist
void initList(pNode *head){
(*head) = (LinkList*)malloc(sizeof(LinkList));
(*head)->next = NULL;
(*head)->data = 9;
}
//insert Element
int insertElem(pNode head, ElemType data){
pNode pInsertNode;
pNode pWork;
pWork = head;
pInsertNode = (LinkList*)malloc(sizeof(LinkList));
//memset(pInsertNode, 0, sizeof(LinkList));
if(pInsertNode == NULL){
return 0;
}
pInsertNode->next = NULL;
pInsertNode->data = data;
while(pWork->next != NULL){
pWork = pWork->next;
}
pWork->next = pInsertNode;
return 1;
}
//print node data one by one
void printList(pNode head){
printf("in the function printList\n");
if(head == NULL){
printf("List is empty----\n");
}
pNode p = head->next;
do{
printf("%d", p->data);
printf("--->");
p = p->next;
}while(p != NULL);
}
//make the LinkList loop
void makeLoop(pNode head){
pNode p = head;
while(p->next != NULL ){
p = p->next;
}
p->next = head->next;
}
//tell if is a loop list?
int isListLoop(pNode head){
int i;
pNode slow = head;
pNode fast = head;
while(fast){
for(i = 0 ; i < FAST_POINT_STEP ; i++){
fast = fast->next;
if(fast == slow)
return 1;
else if(fast == NULL)
return 0;
}
slow = slow->next;
}
return 0;
}
void main(){
int i;
pNode head;
initList(&head);
for(i = 0 ; i < INSERT_NUM ; i++){
insertElem(head, i);
}
makeLoop(head);
//printList(head);
if(isListLoop(head))
printf("is a loop list \n");
else
printf("is not a loop list\n");
}
之前在网上看到有人说,判断一个链表是否有环,还可以使用两个for循环嵌套的方法,当外层循环步进一个节点时,内层循环就遍历外层循环节点之后的所有节点,然后比较内外循环的两个节点。若有节点地址相等,则表明该单链表有循环,反之则不存在循环。这种方法无疑效率比较低。而且如果出现下面这种情况的话,会更加麻烦。