函数删除链接列表中具有给定值的所有节点

时间:2020-07-23 08:22:30

标签: c linked-list singly-linked-list pass-by-value function-definition

功能键(deleteall)获取一个链表和一个值,并删除所有保存该值的节点,然后在更改后返回列表。

 Pointer deleteall(Pointer l, int v)
{
  
  Pointer temp;

  while(l != NULL)
  {
    if(l->val == v) {
      temp = l;
      l = temp ->next;
      free(temp);
      
    }
    if(l == NULL) return l;
    else l = l->next;
  }
  return l;
}

没有错误显示,编译器完成了,并且什么也没有显示,我认为程序进入了无尽的循环。

3 个答案:

答案 0 :(得分:0)

您的函数始终返回空指针。

如果未像在函数定义中那样通过引用传递指向头节点的指针,则该函数必须将指针返回到头节点。

它看起来可能是这样的

Pointer deleteall(Pointer l, int v)
{
    while ( l && l->val == v )
    {
        Pointer temp = l;
        l = l->next;
        free( temp );
    }

    if ( l )
    {
        for ( Pointer current = l; current->next != NULL; )
        {
            if ( current->next->val == v )
            {
                Pointer temp = current->next;
                current->next = current->next->next;
                free( temp );
            }
            else
            {
                current = current->next;
            }
        }
    }

    return l;
}

如果在主节点上指向头节点的指针也被命名为l,则该函数应被命名为

l = deleteall( l, v );

通过引用传递指向头节点的指针时,可以看到一个更简单的函数定义。例如

void deleteall(Pointer *l, int v)
{
    while ( *l != NULL )
    {
        if ( ( *l )->val == v )
        {
            Pointer temp = *l;
            *l = ( *l )->next;
            free( temp );
        }
        else
        {
            l = &( *l )->next;
        }
    }
}

在主函数中可以像这样调用

deleteall( &l, v );

答案 1 :(得分:0)

  1. 您不需要返回指针。您只需要将列表的开头作为参数即可。然后创建一个临时指针,将其初始化为头部指向的位置,然后您就可以开始工作了
  2. 当找到需要删除其val的节点时,请确保将该节点连接到空闲节点的上一个和下一个。因此,链接列表仍保持链接状态

我在此提出一个示例解决方案,假设列表a)头与需要释放的头不相同,并且b)最后一个节点指向NULL。我们保留2个临时指针,分别指向a)Node和b)Node-> next。我们总是检查Node-> next,如果它是一个要发布的,则连接没有它的列表,然后释放它。

void deleteall(Pointer l, int v)
{
  
  Pointer temp, temp2;
  temp2 = l;
  temp = temp2->next;

  while(temp != NULL)
  {
    if(temp->val == v) {
      temp2->next = temp->next;
      free(temp);
      temp = temp2->next

    } else
    {
      temp2 = temp;
      temp = temp->next;
    if(temp == NULL)
      break;

  return;} 

此解决方案可以优化,但对我个人有帮助,尤其是当我绘制带有指针和节点的图时。

答案 2 :(得分:0)

这是一个很短的实​​现。它利用prev指针指向上一个指针,该指针指向当前元素。这样,我们可以轻松地检查当前元素是否存在(列表未耗尽),并沿着列表前进指针,或者如果删除了当前元素,则将指针保持在当前位置,然后下一个替换它。

Pointer deleteall(Pointer l, int v)
{
    Pointer* prev = &l;

    while (*prev != NULL)        // any items after the previous one?
    {
        Pointer curr = *prev;    // yes - so this is our current item
        if (curr->val == v)
        {
            *prev = curr->next;  // link next item to prev
            free(curr);
        }
        else
            prev = & curr->next; // step forward on the list
    }
    return l;                    // a new head of the list
}