Почему я не могу найти бесконечный цикл в моей C-программе для поиска в связанном списке? Программа работает - PullRequest
1 голос
/ 20 октября 2019

Вот моя программа для поиска элемента в связанном списке. Мне говорят, что в моем коде есть бесконечный цикл. Я не знаю где. Программа работает на моем конце, и она не зацикливается на мне. Я действительно не могу понять это. Если у кого-то есть какие-либо предложения или идеи относительно того, на какую часть моего кода мне следует обратиться, чтобы решить проблему, пожалуйста, дайте мне знать. Я действительно в тупике.

struct node
{
    int a;
    struct node *next;
};


void generate(struct node **head, int num)
{
    int i;
    struct node *temp;

    for (i = 0; i < num; i++)
    {
        temp = (struct node *)malloc(sizeof(struct node));
        temp->a = rand() % num;

        if (*head == NULL)
        {
            *head = temp;
            temp->next = NULL;
        }
        else
        {
            temp->next = *head;
            *head = temp;
        }
        printf("%d    ", temp->a);
    }
}

void search(struct node *head, int key, int index)
{
    while (head != NULL)
    {
        if (head->a == key)
        {
            printf("Key found at Position: %d\n", index);
        }

        search(head->next, key, index - 1);
    }
}

void delete(struct node **head)
{
    struct node *temp;
    while (*head != NULL)
    {
        temp = *head;
        *head = (*head)->next;
        free(temp);
    }
}

int main()
{
    struct node *head = NULL;
    int key, num;

    printf("Enter the number of nodes: ");
    scanf("%d", &num);
    generate(&head, num);
    printf("\nEnter key to search: ");
    scanf("%d", &key);
    search(head, key, num);
    delete(&head);
}

Ответы [ 2 ]

1 голос
/ 20 октября 2019

Как уже упоминалось в другом ответе , проблема в том, что вы зацикливаетесь, пока head не является нулевым указателем, но вы никогда не измените head, поэтому он никогда не станет нулевым указателем.

Но есть и другая проблема с функцией search: вам нужно решить, хотите ли вы перебирать список, используя циклы или рекурсию. Вы не должны использовать оба.

Либо используйте циклы

while (head != NULL)
{
    if (head->a == key)
    {
        printf("Key found at Position: %d\n", index--);
    }
    head = head->next;
}

Или используйте рекурсию

if (head != NULL)
{
    if (head->a == key)
    {
        printf("Key found at Position: %d\n", index);
    }
    search(head->next, key, index - 1);
}

Я предполагаю, что вы действительно хотели сделать последнюю альтернативу,но по ошибке использовали while вместо if.

1 голос
/ 20 октября 2019

Посмотрите на вашу search функцию:

void search(struct node *head, int key, int index)
{
    while (head != NULL)
    {
        if (head->a == key)
        {
            printf("Key found at Position: %d\n", index);
        }
        search(head->next, key, index - 1);
    }
}

Теперь пока игнорируйте два «действия», которые происходят в цикле while, и просто подумайте о том, что останавливает выполнение цикла,Предполагая (при самом первом вызове функции), что значение head равно , а не NULL, когда цикл остановится? Конечно, когда head становится NULL - но вы никогда не измените значение head в этом цикле! И рекурсивный вызов search не меняет его в функции, которая в данный момент выполняется! Так что это бесконечный цикл.

Вам нужно назначить head->next на head внутри цикла, например:

void search(struct node *head, int key, int index)
{
    while (head != NULL)
    {
        if (head->a == key)
        {
            printf("Key found at Position: %d\n", index);
        }
        head = head->next; // If list is properly formed, this will get to NULL
        search(head, key, index - 1); // Now we don't need to use the ->next here
    }
}

Кроме того, если вы хотите найти только первое вхождение ключа, вы можете добавить оператор return после printf;в существующем состоянии вы распечатаете все совпадений - но этого может потребоваться, если вы захотите.

...