这是我的程序,用于搜索链接列表中的元素。我被告知我的代码中有一个无限循环。我不知道在哪里。这个程序在我这端运行,但对我来说它并没有保持循环。我真的想不出来。如果有人对我的代码的哪一部分有任何建议或想法,请让我知道。我真的被难住了。

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);
}

最佳答案

看看你的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语句;按原样,您将打印所有匹配项-但这可能是您想要的。

10-07 19:30
查看更多