原理
这里 有一个 比较 简单 的 解法。 设置 两个 指针 p1、 p2。 每次 循环 p1 向前 走 一步, p2 向前 走两步。 直到 p2 碰到 NULL 指针 或者 两个 指针 相等 时 结束 循环。 如果 两个 指针 相等, 则 说明 存在 环。
代码实现
bool whetherListLoop(st_dataNode * head){
if(NULL == head){ /*空链表打环个毛线*/
return false;
}
bool rst = false; /* 默认不是打环的 */
st_dataNode * pos1 = NULL, * pos2 = NULL;
pos1 = pos2 = head;
if(NULL == pos1->next){ /*head后一个节点且下一个为NULL,不可能打环*/
goto out;
}
while(NULL != pos1 && NULL != pos1->next){
/*一个走两步,一个走一步,看看能不能跟的上*/
pos1 = pos1->next->next;
pos2 = pos2->next;
if(pos1 == pos2){
rst = true;
goto out;
}
}
if(pos1 == pos2){
rst = true;
goto out;
}
out:
return rst;
}
void testWhetherLopp(void){
printf("====== %s ===========\n", __func__);
st_dataNode * tail = NULL;
bool rst = false;
rst = whetherListLoop(ghead);
if(rst){
printf("\t List Loop\n");
} else {
printf("\t Not Loop\n");
}
tail = ghead;
while(tail->next != NULL){
tail = tail->next;
}
tail->next = ghead;
rst = whetherListLoop(ghead);
if(rst){
printf("\t List Loop\n");
} else {
printf("\t Not Loop\n");
}
tail->next = NULL;
dumpList(ghead);
return;
}
调试编译
gcc listMain.c list.c -o a.exe -DDEBUG
调试输出
====== testWhetherLopp ===========
Not Loop
List Loop
========= Dump List 0x76d090 ===========
0 4 6 19 22 29 32 47 53 116
===================================