1. 怎样判断一个链表有环
(1)最常用方法
定义两个指针,同时从链表的头节点出发,一个指针一次走一步,另一个指针一次走两步。如果走得快的指针追上了走得慢的指针,那么链表就是环形链表;如果走得快的指针走到了链表的末尾(next指向 NULL)都没有追上第一个指针,那么链表就不是环形链表。
bool IsLoop(NODE *head) {// 假设为带头节点的单链表
if (head == NULL)
return false;
node *slow = head->next; // 初始时,慢指针从头节点开始走1步
if (slow == NULL)
return false;
node *fast = slow->next; // 初始时,快指针从头节点开始走2步
while (fast!=NULL && slow!=NULL){ //当单链表没有环时,循环到链表尾结束
if (fast == slow)
return true;
slow = slow->next; // 慢指针每次走一步
fast = fast->next;
if (fast != NULL)
fast = fast->next;
}
return false;
}
(2)通过使用STL库中的map表进行映射
首先定义 map<NODE *, int> m; 将一个 NODE * 指针映射成数组的下标,并赋值为一个 int 类型的数值。然后从链表的头指针开始往后遍历,每次遇到一个指针p,就判断 m[p] 是否为0。如果为0,则将m[p]赋值为1,表示该节点第一次访问;而如果m[p]的值为1,则说明这个节点已经被访问过一次了,于是就形成了环。