Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 访谈:删除链接列表中的节点_C_Linked List - Fatal编程技术网

C 访谈:删除链接列表中的节点

C 访谈:删除链接列表中的节点,c,linked-list,C,Linked List,节点删除的这种实现是有效的,还是失败了 void remove_node(node *p) { node **i = &node_list; for (;(*i) != NULL && ((*i) != p); *i = ((*i)->next)) ; if (*i != NULL) { (*i) = (*i)->next; } if (p != NULL) { free

节点删除的这种实现是有效的,还是失败了

void remove_node(node *p)
{
    node **i = &node_list;

    for (;(*i) != NULL && ((*i) != p); *i = ((*i)->next)) ;

    if (*i != NULL) 
    {
      (*i) = (*i)->next;
    }

    if (p != NULL) 
    {
      free(p);
    }
}
顺便说一句,据我所知,在我看到的每一个从列表中删除节点的算法中, 有一个变量应该保留上一个指针。此实现缺少此…

否。它不起作用。(是的,我知道,我作弊了——起初我说是的)

作为面试问题的答案,我首先列出以下假设:

  • 节点列表开始时有效(并且正确地以NULL结尾)
  • 这是一个单链表
  • 节点是动态分配的
问题是:
*i==p
时,循环将停止。当
*i->next==p
时,它需要停止-然后它几乎可以工作,但如果p是列表中的第一个节点,它仍然会有问题。

我认为这会产生副作用,即
节点\u列表
不会指向列表的开头。所以头部节点需要存储在其他变量中


顺便说一句,你试过了吗?你得到了什么?

程序中的错误是

  • 头指针(节点列表)不会指向第一个元素,它会指向
    p
  • (*i)=(*i)->下一步
    -这是错误的。应更新上一个节点的下一个指针
  • 下面更新的逻辑将正常工作

    void remove_node(node *p) 
    {     
        node *i = node_list;      
        node *previous_node = NULL;
    
        if((NULL == p) || (NULL == node_list))
        {
            return;
        }
    
        for (; (i != NULL) && (i != p); i = i->next) 
        {
            previous_node = i;
        }
    
        if (i != NULL)      
        {       
            if(NULL == previous_node) // `p` is the first node
            {
                node_list = i->next;
                free(i);
            }
            else //`p` is not the first node
            {
                previous_node->next = i->next;     
                free(i);
            }
        }      
    } 
    

    假设
    参数p为pArg

    for循环之后:-

    for (;(*i) != NULL && ((*i) != p); *i = ((*i)->next)) ;
    
     if (*i != NULL) 
        {
          (*i) = (*i)->next;
        }
    
    if (p != NULL) 
        {
          free(p);
        }
    
    *i=pArg[如果链接列表中存在节点pArg](情况1)或*i=NULL(情况2)

    在第一个if之后:-

    for (;(*i) != NULL && ((*i) != p); *i = ((*i)->next)) ;
    
     if (*i != NULL) 
        {
          (*i) = (*i)->next;
        }
    
    if (p != NULL) 
        {
          free(p);
        }
    
    p=pArg->next(情况1)和无操作(情况2)

    第二个if:-

    for (;(*i) != NULL && ((*i) != p); *i = ((*i)->next)) ;
    
     if (*i != NULL) 
        {
          (*i) = (*i)->next;
        }
    
    if (p != NULL) 
        {
          free(p);
        }
    
    免费(pArg->next);(案例1);在(情况2)中没有操作(如果pArg真的是LL中的节点)

    您删除了pArg指向的节点,而不是pArg本身

    做一点改变:-

    node *prevp=NULL;
    
    for (;(*i) != NULL && ((*i) != p); *i = ((*i)->next))
    {prevp=*i;} 
    
    if (*i != NULL) 
        {
          prevp->next = (*i)->next;
        }
    

    看起来你正在以删除的方式前进。另外,一个while循环可能会提高可读性。我认为你应该试着用可读的方式写它,尽量不要太复杂…@0x90这是一个面试问题,我没有那样写,是的,应该是这样的sophisticated@Mellowcandle删除linkedlist中的节点是一个简单的问题,很抱歉让您失望:(我很高兴你没有那样写,因为像那样写代码的人在他的一生中可能写的代码不多……这是什么样的答案?