Experiment C 1-- C language pointer in the structure and

problem

Implement an algorithm that detects whether there is a single ring linked list, even if there is obtained the inlet ring ring.

analysis

Determine whether the ring: the speed of the pointer method (also called "Tortoise and the Hare"), each move a pointer slow, fast moving pointer every two, if there is a ring, they will meet.

Ring seeking entry: meet the arrival position, the head block pointer movement position of the pointer, every time a mobile, the position is both meet again the inlet ring.

why?

(First "borrowed" a map

 

 The first time meet, slow down the pointer $ x + k $, fast walking pointer $ x + k + mr $ ($ r $ is the length of the loop, $ m \ geq 1 $),

And because the fast speed of the pointer is twice slower pointer, the $ 2 (x + k) = x + k + mr $.

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

Slow pointer has $ k $, the block pointer is set to 0, the step further over $ X $, they will meet the inlet ring.

#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\n", ll_has_cycle(&nodes[0]) ? "a" : "no");
     printf("Entranc:%d\n", 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\n", ll_has_cycle(&nodes[4]) ? "a" : "no");
    printf("Entranc:%d\n", 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\n", ll_has_cycle(&nodes[11]) ? "a" : "no");
    printf("Entranc:%d\n", 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\n", ll_has_cycle(&nodes[18]) ? "a" : "no");
    printf("Entranc:%d\n", 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\n", ll_has_cycle(&nodes[19]) ? "a" : "no");
    printf("Entranc:%d\n", find_cycle_entrance(&nodes[19]));

    printf("Checking length-zero list for cycles. There should be none, ll_has_cycle says it has %s cycle\n", ll_has_cycle(NULL) ? "a" : "no");
    printf("Entranc:%d\n", find_cycle_entrance(NULL));
}

int main() {
    test_ll_has_cycle();
    return 0;
}

 

 

Reference Links: https://blog.csdn.net/qq_36781505/article/details/91401474

Guess you like

Origin www.cnblogs.com/lfri/p/11460392.html