zoukankan      html  css  js  c++  java
  • C语言实验1—— C中的指针和结构体

    问题

    实现一个算法,检测单链表中是否有环,如果有环还要得到环的入口。

    分析

    判断是否有环:快慢指针法(也叫“龟兔赛跑”),慢指针每次移动一位,快指针每次移动两位,如果有环,他们一定会相遇。

    求环的入口:到达相遇的位置时,将块指针移动到头指针的位置,每次移动一位,两者再次相遇的位置就是环的入口。

    为什么呢?

    (先“借”一张图

     第一次相遇时,慢指针走 $x+k$,快指针走 $x+k+mr$($r$ 为环的长度, $m geq 1$),

    又因为快指针的速度是慢指针的两倍,所以 $2(x+k) = x+k+mr$.

    即 $x = mr-k$($m geq 1$),

    慢指针已在 $k$ 处,块指针置0,还过 $x$ 步,它们就会相遇于环的入口。

    #include <stdio.h>
    #include<stdbool.h>
    
    typedef struct node {
        int value;
        struct node *next;
    } node;
    
    bool ll_has_cycle(node *head) {
        if (head == NULL)  return false;
        node* har = head;
        node* tor = head;
    
        while (1)
        {
            if (tor->next != NULL)  tor = tor->next;
            else   return false;
            if (har->next != NULL && har->next->next != NULL)  har = har->next->next;
            else  return false;
    
            if (tor == har)  return true;
        }
    }
    
    int find_cycle_entrance(node *head) {
        if (head == NULL)  return -1;
        node* har = head;
        node* tor = head;
    
        while (1)
        {
            if (tor->next != NULL)  tor = tor->next;
            else   return -1;
            if (har->next != NULL && har->next->next != NULL)  har = har->next->next;
            else  return -1;
    
            if (tor == har)
            {
                har = head;
                while(har != tor)
                {
                    har = har->next;
                    tor = tor->next;
                }
                return har->value;
            }
        }
    }
    
    void test_ll_has_cycle(void) {
        int i;
        node nodes[25]; //enough to run our tests
        for (i = 0; i < sizeof(nodes) / sizeof(node); i++) {
            nodes[i].next = 0;
            nodes[i].value = i;
        }
        nodes[0].next = &nodes[1];
        nodes[1].next = &nodes[2];
        nodes[2].next = &nodes[3];
        printf("Checking first list for cycles. There should be none, ll_has_cycle says it has %s cycle
    ", ll_has_cycle(&nodes[0]) ? "a" : "no");
         printf("Entranc:%d
    ", find_cycle_entrance(&nodes[0]));
    
        nodes[4].next = &nodes[5];
        nodes[5].next = &nodes[6];
        nodes[6].next = &nodes[7];
        nodes[7].next = &nodes[8];
        nodes[8].next = &nodes[9];
        nodes[9].next = &nodes[10];
        nodes[10].next = &nodes[4];
        printf("Checking second list for cycles. There should be a cycle, ll_has_cycle says it has %s cycle
    ", ll_has_cycle(&nodes[4]) ? "a" : "no");
        printf("Entranc:%d
    ", find_cycle_entrance(&nodes[4]));
    
        nodes[11].next = &nodes[12];
        nodes[12].next = &nodes[13];
        nodes[13].next = &nodes[14];
        nodes[14].next = &nodes[15];
        nodes[15].next = &nodes[16];
        nodes[16].next = &nodes[17];
        nodes[17].next = &nodes[14];
        printf("Checking third list for cycles. There should be a cycle, ll_has_cycle says it has %s cycle
    ", ll_has_cycle(&nodes[11]) ? "a" : "no");
        printf("Entranc:%d
    ", find_cycle_entrance(&nodes[11]));
    
        nodes[18].next = &nodes[18];
        printf("Checking fourth list for cycles. There should be a cycle, ll_has_cycle says it has %s cycle
    ", ll_has_cycle(&nodes[18]) ? "a" : "no");
        printf("Entranc:%d
    ", find_cycle_entrance(&nodes[18]));
    
        nodes[19].next = &nodes[20];
        nodes[20].next = &nodes[21];
        nodes[21].next = &nodes[22];
        nodes[22].next = &nodes[23];
        printf("Checking fifth list for cycles. There should be none, ll_has_cycle says it has %s cycle
    ", ll_has_cycle(&nodes[19]) ? "a" : "no");
        printf("Entranc:%d
    ", find_cycle_entrance(&nodes[19]));
    
        printf("Checking length-zero list for cycles. There should be none, ll_has_cycle says it has %s cycle
    ", ll_has_cycle(NULL) ? "a" : "no");
        printf("Entranc:%d
    ", find_cycle_entrance(NULL));
    }
    
    int main() {
        test_ll_has_cycle();
        return 0;
    }

    参考链接:https://blog.csdn.net/qq_36781505/article/details/91401474

  • 相关阅读:
    编码 unicode与utf8
    For WeiWei Server Code
    C#枚举
    一些关于java的笔记
    当众讲话第三章当众讲话的语言要求
    当众讲话第四章当众讲话出彩的资本
    会计要素和会计平衡公式
    当众讲话第一章 当众讲话的八项训练
    金蝶KIS标准版会计软件简单使用
    做事的科学细节与流程》读书笔记第一章
  • 原文地址:https://www.cnblogs.com/lfri/p/11460392.html
Copyright © 2011-2022 走看看