链表插入与删除操作中的头、尾指针

转载 2006年05月23日 21:32:00

[题目]:有一个单链表,它的元素全部是整数。head和tail分别是指向该链表第一个元素(即头元素)和最后一个元素(即尾元素)的全局性指针。请实现调用接口如下所示的两个C语言函数:
                                                   int Delete (element *elem);
                                                   int InsertAfter (element *elem, int data);
Delete函数只有一个输入参数,它就是那个将被删除的元素。InsertAfter函数有两个输入参数,第二个输入参数给出了新元素的取值,它将被插到第一个输入参数所指定的元素的后面。当需要把新元素插入到链表的开头作为新的头元素时,函数InsertAfter的第一个输入参数将被设置为NULL。如果执行成功,这两个函数将返回“1”;否则返回“0”。

      这道题看起来很简单。元素的插入和删除操作都是链表的常用操作,用头指针来定位链表的事情也是大家所接受的。这道题唯一不同寻常的地方是它要求你必须正确的调整好head和tail指针。在编写Delete函数时,链表头元素的删除操作需要特殊对待,我们首先要将待删除元素的指针和head指针进行比较。
         if(elem == head)
         { head = elem->next;
           free(elem);
           return 1;          代码1
      对链表的“腹部”元素进行删除是最普通的情况。我们首先需要一个元素指针来记录链表的当前位置(curpos指针)。在链表中删除一个元素,我们需要找到待删除元素前一个元素的指针并修改其next指针。请认真编写你的遍历循环语句,不要遗漏掉某个元素。如果我们把curpos指针初始化为指向链表头元素,那么“curpos->next”将指向链表的第二个元素。从第二个元素开始遍历循环是不会产生错误的,但一定要先进行比较操作后修改curpos指针,要不燃就会陋漏掉链表的第二个元素。如果curpos指针变成了NULL,说明已经到达了链表的末尾,删除操作不成功。在删除元素时,如果我们删除的正好是尾元素,此时我们已经改变了链表的尾元素,那么tail元素也要做相应的修改:
        if(curpos->next == NULL)
        tail = curpos;
      再考虑特殊情况的例子:0元素和1个元素的链表。0元素链表的Delete函数将返回一个“0”,因为空链表里没有可删除的元素。对于只有一个元素的链表,此时head和tail都指向唯一可删除的元素。当“elem==head”时,elem->next肯定等于NULL,于是Delete函数正确地把head指针设置为NULL,并释放这个元素;但是此时tail指针仍然指向着我们已经释放了的这个元素。也就是说,我们需要特意地把tail指针设置为NULL才算正确地完成了删除操作:
        在代码1的后面加上    if(!head)
                                               tail = NULL;
      对于有且只有2个元素的链表又是怎样的情况呢?删除第一个元素将使head指针指向第二个元素,没有问题;删除第二个元素将使tail指向第一个元素,也没有问题。也就是说,缺少“腹部”元素并不会产生什么意外。
    下面是Delete函数的全部代码:
        int Delete (elem *elem)
        {
          element *curpos = head;
          if(!elem)
            return 0;
          if(elem == head)
           { head = elem->next;
             free(elem);
             if(!head)
               tail = NULL;
             return 1;
           }
         while(curpos)
           {
            if(curpos->next==elem)
              {
                curpos->next=elem->next;
                free(elem);
                if(curpos->next==NULL)
                  tail = curpos;
                return 1;
               }
            curpos = curpos->next;
           }
         return 0;
         }   

      在编写InsertAfter函数的时候,需要考虑的因素与我们前面的分析大同小异。因为这个函数需要为新元素分配内存,所以千万不要忘记检查内存分配操作是否成功以免出现内存泄露。Delete函数中的大体部分特殊情况都需要在InsertAfter函数中加以注意,这两个函数在整体结构上很相似:
         int InsertAfter (element *elem, int data)
          {  element *newelem, *curpos = head;
             newelem = (element *)malloc(sizeof(element));
             if(!newelem)
                return 0;
             newelem->data=data;
             if(!elem)
              {
                newelem->next = head;
                head = newelem;
                if(!tail)
                   tail = newelem;
               }
             while(curpos)
              {
                if(curpos == elem)
                 {
                   newelem->next == curpos->next;
                   curpos->next = newelem;
                   if(!(newelem->next))
                      tail = newelem;
                   return 1;
                  }
                curpos =curpos->next;
              }
            free(newelem);
            return 0;
         }

      这道面试题重点考察了求职者对特殊情况的分析和处理能力。虽说不难,也不太容易做到百分之百的满意,它的确是一道非常有针对性的面试题。面试考试题多少会包含有一些特殊情况,所以我们必须有随时会遇到它们的思想准备。在实际编程工作中,未做适当处理的特殊情况就是程序代码中的bug,而且还是那种很难查找、重现和修正的bug。一般说来,一位在编写代码的同时就已经考虑到各种特殊情况的程序员肯定要比那些只知通过调试去查找bug的程序员来的高明,也更有效率。

相关文章推荐

C语言实现链表之单向链表(八)删除尾结点

C语言实现链表之单向链表(八)删除尾结点     上一篇文章给出了在尾结点之后插入结点的函数,本篇文章将给出删除尾结点的函数。 /*============================...

数据结构:C++链表类及一元多项式的实现时遇到的困难

书上要求一个链表类,一个结点类,不会写。 在别人的博客上看到有四种方式: 复合类:在Node类中定义友元的方式,使List类可以访问结点的私有成员。 嵌套类:在List内部定义Node...

数据结构示例之简单多项式相加

以下为展示简单多项式相加的示例: 1.用c语言实现的版本 #include #include #define MAX_TERMS 100 /* size of terms arr...

运行二级指针在单链表中进行删除操作

一、 二级指针简介 指向指针的指针,称为二级指针二级指针实质上存放的是一级指针的地址 二、...

有一个单项的链表,在没有头结点的情况下,只知道有一个指向结点B的指针p,假设这个结点B不是尾结点,删除该节点B。

问题:有一个单项的链表,在没有头结点的情况下,只知道有一个指向结点B的指针p,假设这个结点B不是尾结点,删除该节点B。 p->data = p->next->data; p->next ...

单链表的基本操作(尾插,尾删,头插,头删,查找,指定位置插入、删除,指定元素删除、全部删除等)

单链表的基本操作(尾插,尾删,头插,头删,查找,指定位置插入、删除,指定元素删除、全部删除等)...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:链表插入与删除操作中的头、尾指针
举报原因:
原因补充:

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