删除单向链表头元素

来源:互联网 发布:手机淘宝评价中心 编辑:程序博客网 时间:2024/06/05 17:50

[题目]:下面是一个用来删除单向链表头元素的函数。请找出其中的漏洞并加以改正。
       void RemoveHead (node *head)
       { free (head);
         head = head->next;
}
        

    这种调试纠错类的考题经常出现在程序设计面试中。我们可以从以下四个比较集中的方面进行检查和分析:
    1.进入函数的数据是否都事先被定义,类型是否都正确无误?
    2. 函数中的每一条语句是否执行正确、正常?
    3.离开函数的数据是否都“去向”明确,格式无误?
       函数的返回值是不是人们所预期的?如果子函数需要改变其调用者(即父函数)中的某个变量,那么它是否正确地做到了这一点?
    4.函数对常见的特殊处理是否进行了处理?
      特别是对以指针为输入参数的函数要着重注意。在该指针为 "NULL"时,往往会无法执行而失败。

    所给的程序中,首先释放了head,然后还将head指针赋了一个新值。着显然是第二种错误。修改的办法也很简单,用一个临时变量来保存head元素的next指针:
       void RemoveHead (node *head)
       {node *temp = head->next;
        free(head);
        head = temp;}
    这个函数没有一个明确的返回值,但它有一个隐含的返回值——这个函数的用途是修改其调用者的head指针值。在C语言里,输入的参数是以值传递的方式进入子函数的,变量不支持引用传递方式进入子函数,也就是说,子函数所使用的是输入参数的一个副本,对这个局部副本的修改不可能在该子函数以外的地方发生作用。也就是说,head = temp语句根本无法正确实现对head指针的赋值。对应的修改办法是采用一个指向变量的指针作为子函数的输入参数,我们需要把一个指向head指针的指针传递给RemoveHead函数作为输入参数。(另外在主程序中调用该RemoveHead函数的语句应相应修改为:RemoveHead(&head);)
       void RemoveHead (node **head)
       {node *temp = (*head)->next;
        free(*head);
        *head = temp;}
     与这道试题有关的特例有2种,一种是仅有一个元素的链表。 另一种是空白链表。对于只有一个元素的链表不会出现问题,它在删除掉那唯一的元素之后会把head设置为“NULL”。如果是空链表,head是一个“NULL”指针,显然我们所做的都是对一个“NULL”指针进行操作。这又是一个错误。所以,我们首先应该判断head是否是一个“NULL”指针,如果是,表明链表为空,不需要做任何的指针操作,直接返回即可。
       void RemoveHead (node **head)
       { node *temp;
         if(head && *head)
           {
             temp =(*head)->next;
             free(*head);
             *head = temp;
            }
        }

原创粉丝点击