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

#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");  
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值