C data structure and algorithm - quickly determine whether the linked list is a loop

Table of contents

Article directory

the code

insert image description here

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


// 定义链表节点结构体
struct ListNode {
    
    
    int val; // 节点值
    struct ListNode *next; // 指向下一个节点的指针
};

/**
 * 判断单向链表是否成环
 * @param head 链表头节点指针
 * @return 成环返回 true,否则返回 false
 */
bool hasCycle(struct ListNode *head) {
    
    
    struct ListNode *slow = head; // 慢指针
    struct ListNode *fast = head; // 快指针

    // 循环访问链表
    while (fast != NULL && fast->next != NULL) {
    
    
        slow = slow->next; // 慢指针每次移动一步
        fast = fast->next->next; // 快指针每次移动两步

        if (slow == fast) {
    
     // 如果慢指针和快指针相遇了,则说明成环了
            return true;
        }
    }

    return false; // 没有成环
}

// 测试用例
int main() {
    
    
    
    // 构造一个有环的链表
    struct ListNode *head = (struct ListNode *)malloc(sizeof(struct ListNode));
    struct ListNode *p1 = (struct ListNode *)malloc(sizeof(struct ListNode));
    struct ListNode *p2 = (struct ListNode *)malloc(sizeof(struct ListNode));
    struct ListNode *p3 = (struct ListNode *)malloc(sizeof(struct ListNode));
    struct ListNode *p4 = (struct ListNode *)malloc(sizeof(struct ListNode));
    struct ListNode *p5 = (struct ListNode *)malloc(sizeof(struct ListNode));
    struct ListNode *p6 = (struct ListNode *)malloc(sizeof(struct ListNode));

    head->val = 1;
    head->next = p1;
    p1->val = 2;
    p1->next = p2;
    p2->val = 3;
    p2->next = p3;
    p3->val = 4;
    p3->next = p4;
    p4->val = 5;
    p4->next = p5;
    p5->val = 6;
    p5->next = p6;
    p6->val = 7;
    p6->next = p3; // 环的入口是 p3

    bool has_cycle = hasCycle(head);
    printf("%s\n", has_cycle ? "链表成环" : "链表无环");

    // 释放内存
    free(head);
    free(p1);
    free(p2);
    free(p3);
    free(p4);
    free(p5);
    free(p6);

    return 0;
}

Guess you like

Origin blog.csdn.net/Jmilk/article/details/130415386