首页 > 解决方案 > 卸载功能的另一个问题,节点设置为 null 正在以某种方式重新填充

问题描述

我正在制作一个从内存中释放哈希表的函数。目前,我只是试图将节点设置为 NULL 以确保它正确迭代。但是我得到了我不明白的输出。

这是我当前的哈希表:

在此处输入图像描述

这是我目前的输出。这是一个无限循环:

在此处输入图像描述

这是我的代码:

bool unload(void)
{
    // For all elements in the hash table
    for (int i = 0; i < N; i++) 
    {
        // Until break...
        while (1)
        {
            // Set traversal node at hash index i, set trailing traversal node to NOLL
            node *curr = table[i];
            printf("start CURR WORD: %s (%p)\n", curr->word, curr); // DEBUG
            node *prev = NULL;

            // If current is NULL, meaning the index head is null, break
            if (curr == NULL)
            {
                printf("CURR is NULL: BREAKING...\n"); // DEBUG
                break;
            }
            
            // if the index head is not NULL, but its' next pointer is NULL, set current to NULL, next iteration
            if (curr->next == NULL)
            {
                printf("HEAD (%s)->Next: NULL, SETTING HEAD TO NULL...\n", curr->word); // DEBUG
                curr = NULL;
                continue;
            }

            // While current is not null, set trailing traversal node to current, set current to its next pointer
            while (curr != NULL)
            {
                printf("CURR is not NULL: (%s), NEXT...\n", curr->word); // DEBUG
                prev = curr;
                curr = curr->next;
            }

            // when current is NUll, set trailing traversal node to NULL
            printf("CURR IS NULL, SETTING PREVIOUS (%s) TO NULL...\n", prev->word);
            prev = NULL;
            printf("PREV WORD: %s\n", prev->word);
        }
    }

    return true;
}

第一个if条件,if (curr == NULL),似乎触发得很好。table[0]NULL,所以它打破了 的第一次迭代while (1)。其余的在做什么,我不明白。正如预期的那样,它将跳过前两个节点,登陆NULL. 然后,显然,它将前一个节点设置为NULL,就像它应该的那样。但是在 的下一次迭代中while (1),它应该设置为的节点NULL仍然被填充,尽管 command ,并且尽管在该命令(和)触发prev = NULL;之前和之后的两个打印语句也是如此。printf("CURR IS NULL, SETTING PREVIOUS (%s) TO NULL...\n", prev->word);printf("PREV WORD: %s\n", prev->word);

有人可以告诉我这里出了什么问题吗?为什么设置为 NULL 的节点会在下一次迭代中重新填充?提前致谢。

编辑:这是我想要实现的目标......

LIST 00: { } LIST 01: {NODE 1, NODE 2, }

UNTIL THE HEAD IS NULL
    IF the head is NULL
        BREAK

    IF the head is not NULL, but its NEXT pointer is NULL
        Set head to NULL
        next iteration

    IF neither the head nor its next pointer are NULL
        Move to the next node until you reach NULL

    IF the current node is NULL
        Set the previous node to NULL

在 List 00 中,第一个IF遇到了,然后就中断了。在列表 01 中,遇到第三个IF,它移动到NULL。然后遇到第四个IF,它之前的节点应该设置为NULL. 在迭代 2 开始时,它应该如下所示:

LIST 00: { } LIST 01: {NODE 1, }

在这种情况下,满足第二个IF。它应该将 head 设置为NULL,然后继续下一次迭代:

LIST 00: { } LIST 01: { }

现在,第一个IF满足了,所以它应该打破while (1)循环并继续循环中的下一个迭代for

标签: ccs50

解决方案


无限循环是由while(1)循环引起的。在顶部,curr设置为table[i]。在循环中,curr 设置为 null,但这并不重要,因为break语句永远不会被命中,并且 curr 在循环顶部被重置为相同的值。

我评论了代码以帮助解释流程:

bool unload(void)
{
    // For all elements in the hash table
    for (int i = 0; i < N; i++) 
    {
        // Until break...
        while (1)
        {
            // Set traversal node at hash index i, set trailing traversal node to NOLL
            node *curr = table[i];  // <<<<<<< curr set to same value, curr in NOT null, and i is the same as last loop
            printf("start CURR WORD: %s (%p)\n", curr->word, curr); // DEBUG
            node *prev = NULL;

            // If current is NULL, meaning the index head is null, break
            if (curr == NULL)  // <<<<<<<<<<<< skip this, curr is NOT null
            {
                printf("CURR is NULL: BREAKING...\n"); // DEBUG
                break;  // <<<< never gets here
            }
            
            // if the index head is not NULL, but its' next pointer is NULL, set current to NULL, next iteration
            if (curr->next == NULL)  // <<<<<<<<<  skip this, next is NOT null
            {
                printf("HEAD (%s)->Next: NULL, SETTING HEAD TO NULL...\n", curr->word); // DEBUG
                curr = NULL;
                continue;
            }

            // While current is not null, set trailing traversal node to current, set current to its next pointer
            while (curr != NULL)  //  <<<<<<<<<< move curr forward until curr = null
            {
                printf("CURR is not NULL: (%s), NEXT...\n", curr->word); // DEBUG
                prev = curr;
                curr = curr->next;
            }
             
            //   <<<<<<<<<<<<<<<<<<<   at this point, curr = null

            // when current is NUll, set trailing traversal node to NULL
            printf("CURR IS NULL, SETTING PREVIOUS (%s) TO NULL...\n", prev->word);  // <<<< no curr change
            prev = NULL;                                                             // <<<< no curr change
            printf("PREV WORD: %s\n", prev->word);                                   // <<<< no curr change
        }
    }

    return true;
}

- - - - 更新 - - - -

根据更新后的帖子,此代码应获得正确的结果:

bool unload(void)
{
    // For all elements in the hash table
    for (int i = 0; i < N; i++) 
    {
        node *curr = table[i];  // set head
        if (curr == NULL)  continue;  // skip, go to next head
        curr = curr->next; // top of linked list
        
        // set linked list elements to null
        while (curr != NULL) 
        {
            printf("CURR is not NULL: (%s), NEXT...\n", curr->word);
            node *prev = curr;
            curr = curr->next
            printf("SETTING PREVIOUS (%s) TO NULL...\n", prev->word);
            prev = NULL;
            printf("PREV WORD: %s\n", prev->word);
        } // while curr
    } // for i  
}

推荐阅读