数据结构——判断单链表是否有环

本文详细介绍了如何通过单指针遍历链表并利用快慢指针技巧检测链表是否存在循环,包括初始化链表、插入元素、创建循环以及判断是否为循环链表的过程,并讨论了循环链表的常见实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

#define INSERT_NUM 100
#define FAST_POINT_STEP 2

typedef int ElemType;

typedef struct LNode{
    ElemType data;
    struct LNode *next;
}LinkList, *pNode;

//init the linklist
void initList(pNode *head){
    (*head) = (LinkList*)malloc(sizeof(LinkList));
    (*head)->next = NULL;
    (*head)->data = 9;
}

//insert Element
int insertElem(pNode head, ElemType data){

    pNode pInsertNode;
    pNode pWork;
 
    pWork = head;

    pInsertNode = (LinkList*)malloc(sizeof(LinkList));
    //memset(pInsertNode, 0, sizeof(LinkList));
    if(pInsertNode == NULL){
        return 0;
    }
    pInsertNode->next = NULL;
    pInsertNode->data = data;

    while(pWork->next != NULL){
        pWork = pWork->next;
    }
    pWork->next = pInsertNode;
    return 1;
}

//print node data one by one
void printList(pNode head){
    printf("in the function printList\n");
    if(head == NULL){
        printf("List is empty----\n");
    }
    pNode p = head->next;
    do{
        printf("%d", p->data);
        printf("--->");
        p = p->next;
    }while(p != NULL);
    
}

//make the LinkList loop
void makeLoop(pNode head){
    pNode p = head;
    while(p->next != NULL ){
        p = p->next;
    }
    p->next = head->next;
}

//tell if is a loop list?
int isListLoop(pNode head){
    int i;
    pNode slow = head;
    pNode fast = head;
    while(fast){
        for(i = 0 ; i < FAST_POINT_STEP ; i++){
            fast = fast->next;
            if(fast == slow)
                return 1;
            else if(fast == NULL)
                return 0;
        }
        slow = slow->next;
    }
    return 0;
}

void main(){
    int i;
    pNode head;
    initList(&head);
    
    for(i = 0 ; i < INSERT_NUM ; i++){
        insertElem(head, i);
    }
    makeLoop(head);
    //printList(head);
    if(isListLoop(head))
        printf("is a loop list \n");
    else
        printf("is not a loop list\n");

}

        之前在网上看到有人说,判断一个链表是否有环,还可以使用两个for循环嵌套的方法,当外层循环步进一个节点时,内层循环就遍历外层循环节点之后的所有节点,然后比较内外循环的两个节点。若有节点地址相等,则表明该单链表有循环,反之则不存在循环。这种方法无疑效率比较低。而且如果出现下面这种情况的话,会更加麻烦。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值