当前位置: 首页 > 知识库问答 >
问题:

c - C语言快慢链表,这样实现为什么不行?

凌琦
2023-05-19

C语言快慢链表判断链表是否有环

#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 (slow != NULL && fast != 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;
}

hasCycle函数while(slow != NULL && fast !=NULL)时会报错
那为什么写成while(slow != NULL && fast->next != NULL)就没问题啊,快慢指针不是当slow和fast相遇的时候,证明链表有环吗?当slow和fast都不为空时,slow向后移动一位,fast移动两位,当他们相遇的时候即链表有环,若slow和fast为空则无环。

共有1个答案

嵇星海
2023-05-19

fast != NULL 会报错的原因,因为你循环里面 fast = fast->next->next,指向了下一个节点的下一个节点。

 类似资料:
  • 本文向大家介绍C语言单链表的实现,包括了C语言单链表的实现的使用技巧和注意事项,需要的朋友参考一下 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。 链表结构: SList.h SList.cpp Test.cpp 以上内容是小编给大家介绍的C语言单链表的实现代码,希望对大家有所帮助!

  • 本文向大家介绍C语言实现链表贪吃蛇,包括了C语言实现链表贪吃蛇的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了C语言实现贪吃蛇的具体代码,供大家参考,具体内容如下 用C语言链表写的贪吃蛇(程序设计时做的,做的不好大佬勿喷) 借助游戏内容分析贪吃蛇所需的功能主要包括这几块: 1.移动光标模块 2.打印地图模块和基本规则信息 读取最高分文件 3.打印初始蛇模块 打印时给予蛇的初始移动方向

  • 本文向大家介绍C语言实现单链表反转,包括了C语言实现单链表反转的使用技巧和注意事项,需要的朋友参考一下 一、理解指针 看懂链表的结构并不是很难,但是一旦把它和指针混在一起,就很容易让人摸不着头脑。所以,要想写对链表代码,首先就要理解好指针。   有些语言有“指针”的概念,比如 C 语言;有些语言没有指针,取而代之的是“引用”,比如 Java、Python。不管是“指针”还是“引用”,实际上,它们的

  • 本文向大家介绍C语言实现单链表实现方法,包括了C语言实现单链表实现方法的使用技巧和注意事项,需要的朋友参考一下 C语言实现单链表实现方法 链表和我们之前实现过的顺序表一样,都是简单的数据结构,链表分为单向链表、双向链表、循环链表。而单向链表又分为两种实现方法,一种为带头节点的单链表,一种为不带头节点的单链表。我们来具体看看不带头节点的单链表的实现 单链表:它是一种链式存储的线性表,用一组地址任意的

  • 我需要在向量中找到max元素,所以我使用了,但我发现它是一个非常慢的函数,所以我编写了自己的版本,并设法获得更好的x3性能,下面是代码: 输出: 平均而言,要比多花费x3个时间。那么为什么我能够这么容易地创建一个更快的std函数呢?既然std这么慢,我是不是应该停止使用std并编写自己的函数呢? 注意:一开始我以为这是因为我在for循环中使用了andinteger而不是迭代器,但现在看来这并不重要

  • 本文向大家介绍C语言链表实现贪吃蛇游戏,包括了C语言链表实现贪吃蛇游戏的使用技巧和注意事项,需要的朋友参考一下 阅读学习了源代码,并做了简单的注释和修改,里面只用了链表数据结构,非常适合C语言入门者学习阅读。 程序可在VS2013下编译运行。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。