在 C 中删除链表的所需元素时出现问题

Problem with deleting a desired element of the linked list in C

提问人:muniek7 提问时间:10/31/2023 最后编辑:chqrliemuniek7 更新时间:11/22/2023 访问量:77

问:

我遇到了一个问题,我无法删除具有给定位置的链表元素。我需要删除一个值不均匀的元素(我的列表是 1 到 100 之间的数字)。

以下是我的两个功能:

void Delete_Node(Queue *queue, int position)
{
    Node *oldNode;
    Node *NEXT;
    Node *prev;
    int i;
    
    int deleted_number;
    
    if (position == 1)
    {
        oldNode = queue->head;
        deleted_number = queue->head->value;
        
        queue->head = queue->head->next;
        
        free(oldNode); 
        
        queue->size--;  
    }
    else
    {
        prev = queue->head;
        
        for (i = 1; i < position - 1; i++)
            prev = prev->next;
        
        oldNode = prev->next;
        NEXT = prev->next->next;
        
        oldNode = NULL;
        
        prev->next = NEXT;
        
        queue->size--;  
        
    }
    printf("\nDeleted: %d", deleted_number);
}

void DeleteUneven(Queue *queue)
{
    int pos = 1;
    Node *temp;
    temp = queue->head;
    
    while (1)
    {
        if (temp != NULL)
        {
            if (pos == 1)
            {
                if (temp->value % 2 == 1)
                {
                    Delete_Node(queue, pos);
                    temp = queue->head;
                    pos--;
                }
                else
                    temp = temp->next;
                
                pos++;
            }
            else
            {
                if (temp->value % 2 == 1)
                {
                    Delete_Node(queue, pos);
                    pos--;
                }
                else
                    temp = temp->next;
                
                pos++;  
            }
        }
        else
            break;
    }
}

使用功能后的输出

DeleteUneven(list_of_numbers_form_1_to_100);

Deleted 1
Deleted 1
Deleted 1
...

我认为问题出在功能上,当我试图使一个成为.但我不知道......我还在学习,这个概念对我来说是新的。Delete_Nodetemp->nexttemp->next->next

c 链接列表

评论

2赞 William Pursell 10/31/2023
没有“main”功能:stackoverflow.com/help/minimal-reproducible-example
0赞 Ted Lyngmo 10/31/2023
与其在这里进行实时编码,不如离线准备一个最小的可重现示例,并在完成后进行演示。
0赞 Sven Nilsson 10/31/2023
您的代码存在几个问题:您的“temp”在调用 Delete_Node 后变得无效,但之后您继续使用它。此外,该代码的效率非常低,因为Delete_Node将位置作为参数 - 它应该直接使用 Queue 指针。完全没有必要跟踪位置!

答:

0赞 storsan 11/21/2023 #1

函数中存在问题。当奇数节点被删除时,代码需要移动到队列中的下一个节点 (),以继续 while 循环的下一次迭代。您正在处理在偶数节点未被删除时条件的 else 部分到下一个节点的移动。DeleteUneven()pos != 1temp->nextpos != 1

建议的更改:

if (temp!=NULL)
        {
            if(pos == 1)
            {
                if(temp->value%2==1)
                {
                    Delete_Node(queue,pos);
                    temp = queue->head;
                    pos--;
                }
                else
                    temp = temp->next;
                pos++;

            }
            else
            {
                if(temp->value%2 == 1)
                {
                    temp=temp->next; //save the next node's adress before deleting current node
                    Delete_Node(queue,pos);
                    pos--;

                }
                else
                    temp = temp->next;
                pos++;
            }
        }

另一个问题出在函数上。如果节点不是头节点(),也要设置节点的编号,以便以后可以打印。对于这种情况,还要释放已删除节点()的内存:Delete_Node()deleted_numberqueue-> headoldNode

    if (position == 1)
    {
        oldNode = queue->head;
        deleted_number = queue->head->value;
        queue->head = queue->head->next;
    }
    else
    {
        prev = queue->head;
        for (i = 1 ; i < position - 1 ; i++) {
            prev = prev->next;
        }
        deleted_number=prev->next->value; 
        oldNode = prev->next;
        NEXT = prev->next->next;    
        prev->next = NEXT;
    }
    free (oldNode); 
    queue->size--;
    printf("\nDeleted: %d qsz=%d",deleted_number, queue->size);