LeetCode环形链表(简单)

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/linked-list-cycle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 

 这道题我的思路是使用快慢指针,定义慢指针slow和块指针fast,slow每次移动一位,fast指针每次移动两位。while(fast != NULL && fast->next != NULL)判断链表是否为空,若fast == NULL则链表为空,若fast->next == NULL则链表只有一个值,链表无环。

若均为空,则执行while循环,当slow慢指针和fast快指针相遇时,链表有环。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
typedef struct Node {
    int val;
    struct Node* next;
}Node, * ListNode;
ListNode LinkListInit();
bool createTail(ListNode L);
bool MakeLoop(ListNode L, int i);
bool hasCycle(ListNode L);
void printLinkList(ListNode L);
ListNode LinkListInit() {
    Node* L;
    L = (Node*)malloc(sizeof(Node));   //申请结点空间 
    if (L == NULL) { //判断是否有足够的内存空间 
        printf("申请内存空间失败\n");
    }
    L->next = NULL;//将next设置为NULL,初始长度为0的单链表 
    return L;
}
//输入一个链表的值
bool createTail(ListNode L) {
    int x;
    Node* s, * r = L;
    printf("输入一个链表的值:\n");
    scanf("%d", &x);
    while (x != 9999) {
        s = (Node*)malloc(sizeof(Node));
        s->val = x;
        r->next = s;
        r = s;
        scanf("%d", &x);
    }
    r->next = NULL;
    return true;
}

//构造一个带环的链表
bool MakeLoop(ListNode L, int i) {
    int j = 1;
    ListNode p,q;
    Node *s ,* t;//s为特定的结点,t为最后一个结点
    p = L->next;
    s = NULL;
    if (i == 0) {//若i等于0,则返回头结点
        return L;
    }
    if (i < 1) {//若i无效则返回NULL
        return NULL;
    }
    while (p->next != NULL) {
        if (j < i) {//找到指定结点时,用s记录位置
            s = p;
        }
        p = p->next;
    }
    t = p;//跳出while循环时,p已经指向了最后一个结点
    //构造循环
    t->next = s->next;
    return true;
}

//通过快慢指针来判断链表是否有环
bool hasCycle(ListNode L) {
    ListNode slow, fast;
    slow = L;
    fast = L;
    while ( fast != NULL && fast->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast)
            return true;
    }
    return false;
}


//输出链表
void printLinkList(ListNode L)
{
    ListNode p;
    p = L->next;
    if (p == NULL) {
        printf(" ");
    }
    while (p)
    {
        printf("%d ", p->val);
        p = p->next;
    }
    printf("\n");
}


int main(void) {
    int ch,i;
    ListNode L1, L2,R,L;
    L1 = LinkListInit();
    L2 = LinkListInit();
    L = LinkListInit();
    R = LinkListInit();

    while (1) {
        printf("输入0退出程序\n");
        printf("输入1创建一个链表\n");
        printf("输入2创建一个带环的单链表\n");
        printf("输入3判断一个链表是否有环\n");
        printf("请选择您要进行的操作:\n");
        scanf("%d", &ch);
        switch (ch)
        {
        case 0:
            printf("已退出。\n");
            exit(0);
            break;
        case 1:
            createTail(L);
            break;
        case 2:
            printf("输入循环链表指向的结点位置。\n");
            scanf("%d", &i);
            if (MakeLoop(L, i)) {
                printf("创建环形链表成功\n");
            }
            else {
                printf("创建环形链表失败\n");
            }
            break;
        case 3:
            if (hasCycle(L)) {
                printf("true\n");
            }
            else{
                printf("false\n");
            }
            break;
        default: printf("输入的指令有误,请重新输入。\n");
        }
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值