判断链表是否有环的两种方式和创建有无环的方法
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");
}
#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");
}
相关文章推荐
- 总结:android 创建快捷方式的两种方式+判断是否已经创建+删除快捷方式
- 判断链表是否有环(两种方法)
- 链表是否有环的两种判断方法
- Java判断链表是否有环的两种实现方法
- if (document.all&&document.getElementById) 判断浏览器是否同时支持documnet.getElementById和document.all两种表述方式(方法)
- android判断快捷方式是否已经创建的方法
- Android添加(创建)、删除及判断是否存在桌面快捷方式的方法
- 【java基础 13】两种方法判断hashmap中是否形成环形链表
- SQLITE 创建表 并判断表是否存在的两种方法
- 总结:android 创建快捷方式的两种方式+判断是否已经创建+删除快捷方式
- 【java基础 13】两种方法判断hashmap中是否形成环形链表
- android 创建快捷方式的两种方式+判断是否已经创建+删除快捷方式
- android 获取路径目录方法以及判断目录是否存在,创建目录
- C中判断目录,文件是否存在,创建目录,求目录或文件大小的方法(转)
- js中判断文本框是否为空的两种方法
- js中判断文本框是否为空的 两种方法
- VC中判断目录,文件是否存在,创建目录的方法
- 判断浏览器是否通过ssl方式访问的方法
- sql判断临时表是否存在和创建临时表的方法
- C#两种创建快捷方式的方法