判断链表中是否存在环,可以使用双重循环但是时间复杂度为O(n^2),经典做法就是采用快慢指针来解决该问题
如何确定链表中有环:
设置p,q两个指针,p为慢指针,q为快指针,p每次向前移动一个结点,q每次向前移动两个结点,慢指针的作用就是为了保证遍历完所有的结点,而快指针的作用就是为了当慢指针进入环中时,快速追上慢指针,达到确定链表中存在环的目的
// 判断链表中是否有环
int hasRing(LinkList *L) {
LinkList *p;
LinkList *q;
while (p!= NULL && q != NULL && q->next != NULL) {
p = p->next; //慢指针先走一步
if(q->next != NULL) {
q = q->next->next;
}
if(p == q) {
return 1;
}
}
return 0;
}
如何确定环的长度:
接上面的问题,p为慢指针,q为快指针,从第一次相遇的地方 继续进行“快指针”的遍历,此时快指针的步伐为一次一步,设置一个变量count来记录个数,当快慢指针再次相遇的时候,count的值就是环中结点的个数
int getRingCount(LinkList *L) {
LinkList *p;
LinkList *q;
while (p!= NULL && q!= NULL && q->next != NULL) {
p = p->next; //慢指针走一步
if(q->next != NULL) {
q = q->next->next; //快指针走两步
}
if(p == q) {
break;
}
}
q = q->next;
int count = 1; //因为快指针走了一次啦
while (p != q) {
q = q->next;
count++;
}
return count;
}