C语言面试题之——判断一条单链表有没有环

     给一条链表,判断有没有环。

     分析:如果一条链表没环,那么它的尾节点的next比为NULL,否则就有环。那么给一条链表的时候如何判断有没有环呢,办法是定义两个指针,

一个跑的快,一个跑的慢,如果快的指针走的结果为NULL,那么就是一个无环链表,否则快的指针肯定在某一个节点处追上慢的指针,这时候就会断定

这条链表有环。

    代码如下:

/*************************************************************************
    > File Name: circle.c
    > Author: hai--feng
    > Mail: haifeng@126.com
    > Created Time: Wed 27 Jun 2012 05:11:50 PM CST
 ************************************************************************/

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>

typedef struct node_t
{
    struct node_t *next;
    int data;

}node_t;

node_t * Getlink(node_t *head, int *group, int count)
{
    int cout = count;
    int *pgroup = group;
    node_t *new_node = NULL;
    node_t *ptr = NULL;

    assert(group);
    
    for( ; cout > 0; cout--)
    {
        new_node = (node_t *)malloc(sizeof(node_t));
        new_node->next = NULL;
        new_node->data = *pgroup++;
        
        if(NULL == head)
        {
            head = new_node;
            ptr = head;
        }
        else
        {
            ptr->next = new_node;
            ptr = new_node;
        }
    }

    ptr = NULL;
    pgroup = NULL;

    return head;
}

node_t * Getcirclelink(node_t *head, int *group, int count)
{
    int cout = count;
    int *pgroup = group;
    node_t *new_node = NULL;
    node_t *ptr = NULL;

    assert(group);

    for( ; cout > 0; cout--)
    {
        new_node = (node_t *)malloc(sizeof(node_t));
        new_node->next = NULL;
        new_node->data = *pgroup++;

        if(NULL == head)
        {
            head = new_node;
            ptr = head;
        }
        else
        {
            ptr->next = new_node;
            ptr = new_node;
        }
    }
    ptr->next = head->next;

    ptr = NULL;
    pgroup = NULL;

    return head;
}

void Printlink(node_t *head)
{
    while(1)
    {
        if(NULL != head)
        {
            printf("%d\n",head->data);
            head = head->next;
        }
        else
        {
            break;
        }
        sleep(1);
    }
}

void Checklist(node_t *head)
{
    node_t *runfast = NULL;
    node_t *runslow = NULL;

    assert(head);

    //快指针
    runfast = head;
    //慢指针
    runslow = head;

    while(1)
    {
        if(NULL != runfast->next)
        {
            runfast = runfast->next->next;
        }
        else
        {
            runfast = runfast->next;
        }
        runslow = runslow->next;

        if(NULL == runfast)
        {
            runslow = NULL;
            printf("this link is no circle!\n");
            break;
        }
        if((runfast == runslow) && (NULL != runfast))
        {
            printf("fast point catch slow point data is %d, %d\n",runfast->data,runslow->data);
            printf("this link have a circle!\n");
            runslow = NULL;
            runfast = NULL;
            break;
        }
    }
}

int main(void)
{
    int ret = 0;
    int groupf[] = {1,2,3,4,5,6,7};
    int groups[] = {1,2,3,4,5,6,7,8,9};
    node_t *fhead = NULL;
    node_t *shead = NULL;

    //获取一个无环链表
    fhead = Getlink(fhead, groupf, 7);

    //获取一个有环链表
    shead = Getcirclelink(shead, groups, 9);
   

    //判断两条链表有没有环   

    Checklist(fhead);
    Checklist(shead);

    //打印两条链表
    Printlink(fhead);
    Printlink(shead);

    return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值