判断一个非空单向链表是否带环,带环返回1,不带环返回0
注意:如果链表带环,一定是尾部带环(因为每个结点中只有一个指向其直接后继的指针)
**方法:**长短指针遍历链表,如果两指针指向的结点可以相遇,证明带环;
(形象的说 操场跑圈扣圈了)
int Ring(ElemSN *h)
{
ElemSN *p,*q;
for(q=h,p=h->next ; q-p&&p&&p->next ; q=q->next,p=p->next->next);
if(!(p-q)) return 1;
else return 0;
}
完整代码:(自己创建了一个循环链表)
#include<stdio.h>
#include<stdlib.h>
#define N 6
typedef struct node{
int data;
struct node *next;
}ElemSN;
ElemSN * Greatlink(int a[])
{
ElemSN *t,*p,*h;
h=NULL;
for(int i=0;i<N;i++)
{
p=(ElemSN*)malloc(sizeof(ElemSN));
p->data=a[i];
if(!h){ //头结点
p->next=p;
h=t=p;
}
else{
p->next=h;
t=t->next=p;
}
}
return h;
}
int Ring(ElemSN *h)
{
ElemSN *p,*q;
for(q=h,p=h->next ; q-p&&p&&p->next ; q=q->next,p=p->next->next);
if(!(p-q)) return 1;
else return 0;
}
void Printlink(ElemSN*h)
{
ElemSN *p=h;
do{
printf("%5d",p->data);
p=p->next;
}
while(p!=h);
}
int main(void)
{
int a[]={1,2,3,4,3,6};
ElemSN*head;
head=Greatlink(a);
printf("创建的单向链表为:\n");
Printlink(head);
if(Ring(head)){
printf("\n带环\n");
}
else
printf("\n 不带环");
}