删除单向链表头元素

转载 2006年05月25日 18:08:00

[题目]:下面是一个用来删除单向链表头元素的函数。请找出其中的漏洞并加以改正。
       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;
            }
        }

相关文章推荐

单向循环链表创建、遍历、插入、删除、查找(按位置,按元素值)、清空、销毁

SinglyLinkedCirculayList.h #include "stdafx.h" #include "iostream" using namespace std; typedef str...

单向链表的创建、遍历、求长、判存、判空、插入、删除、查找(按位置或元素)、合并

linkedlist.h #include "stdafx.h" #include "iostream" using namespace std; typedef struct LNode { i...

链表(四)——带表头的单向链表

1.带表头的单向链表 (1)不带表头的单向链表在实现插入和删除时必须区分头结点和其他节点的处理。 (2)使用带表头的单向链表的好处:不用考虑头结点的单独处理。 表头节点:数据域没有值,指针域指向...

判断带表头的单向循环链表La是否递增

原题:编程判断带表头的单向循环链表La是否递增。 分析:判断链表是否递增由函数IsIncrease()实现,其算法思想:令p指向链表的第一个结点,即指向头结点的后继,如果p所指结点的值比其后继结点的值...

不带表头结点的单向链表总结

程序代码: #include #include struct node { char name[20]; int num; struct node *next...

查找一个单向链表中倒数第K个元素

查找一个单向链表中倒数第K个元素

以k个元素为一组反转单向链表

问题: 以k个元素为一组,反转单向链表。比如: 输入: 1->2->3->4->5->6->7->8->null and k = 3 输出:3->2->1->6->5->4->8->7->n.....

JS 通过表单向 Action 传递元素

JS 通过表单元素的 name 属性,向 Action 传递表单元素,实现数据传递。HTML 中元素的 name 属性,如 csUser.userId 等,实现表单元素与 Action 对应 Bean...

C语言单向动态链表程序,实现链表的建立,合并,重新排序,链表元素的插入与删除,以及根据元素成员的值进行元素删除。

C语言单向动态链表程序,实现链表的建立,合并,重新排序,链表元素的插入与删除,以及根据元素成员的值进行元素删除。
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)