您的位置:首页 > 其它

判断链表是否有环的两种方式和创建有无环的方法

2016-08-24 20:56 459 查看
#include <stdio.h>
#include <malloc.h>
typedef struct Huan
{
int a;
struct Huan * next;

}H;

//从这开始是有无环链表的创建方法:
H * creatH(int n , int m) //创建一个带有环的链表, n是总链节数, m是在何处开始有的环
{
H * head , * p , * q , * temp;
head = (H *)malloc(sizeof(H));
p = head;
int i = 1; //i是计数的
while( i <= n )
{
if( i <= m )
{
q = (H *)malloc(sizeof(H));
q->a = i ++;
p->next = q;
p = q;
temp = p;
}
else
{
q = (H *)malloc(sizeof(H));
q->a = i ++;
q->next = temp;
p->next = q;
p = q;
}
}
return head->next;
}
H * creatNH(int n) //创建一个不带环的链表 n是链表的长度
{
H * head , * p , * q;
head = (H *)malloc(sizeof(H));
p = head;
int i = 1;
while ( i <= n)
{
p->a = i ++;
q = (H *) malloc (sizeof(H));
p->next = q;
p = q;
}
p->next = NULL;
return head;

}

//从这开始是可以输出有无环的函数:
void showH(H * p,int n) //遍历一个带有环的链表
{
int i = 1;
while( i < n )
{
printf("%d-->" , p->a);
p = p->next;
i ++;
}
printf("%d\n" , p->a);
}
void showNH(H * p) //遍历一个不带环的链表
{
while( NULL != p->next )
{
printf("%d->" , p->a);
p = p->next;
}
printf("\n");

}

//从这开始是两种判断是否有链表的方法:
//比较步数的方法
int apd(H * p)
{
H * q , * head;
head = p ;
int pa = 0 ; //计head的步数
while(head) //head结点存在
{
q = p;
int pb = 0 ; //计q的步数
while(q) //q结点不为空
{
if( head == q )
{
if( pa == pb )
break;
else
{
printf("环的位置在第%d个结点处。\n\n" , pb+1);
return 1;
}
}
q = q->next;
pb++;
}
head = head->next;
pa++;
}
return 0;
}
//利用快慢指针的方法
int bpd(H * head)
{
printf("\n\n");
int step1 = 1;
int step2 = 2;
H * p = head;
H * q = head;
while( p != NULL && q != NULL && q->next != NULL )
{
p = p->next;
if( q->next != NULL)
q = q->next->next;
printf("p:%d , q:%d\n", p->a , q->a);
if( p== q )
return 1;
}
return 0;
}

//主函数测试
int main()
{
H * p;
p = creatH(20 , 4);
showH(p,20);
if( bpd(p) )
printf("对。\n");
else
printf("不对。\n");
p = creatNH(10);
showNH(p);
if( apd(p) )
printf("对。\n");
else
printf("不对。\n");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: