问答题 编写一算法,删除单链表中值相同的多余结点,即:若链表中有多个结点具有相同的数据域值,只保留其中一个结点,其余结点均从链表中删去,使得最后得到的链表中的所有结点的数据域都不相同。
【正确答案】(1)数据结构
   采用带有头结点的单链表定义。
   (2)思路
   用两个PNode类型的指针p,q来帮助完成所要求的删除操作。p从第一个结点开始向后扫描,q从p的后继结点开始向后扫描。每当发现p->info==q->info时,删除q指向的结点。为了方便删除操作,再使用一个PNode类型的指针r,r总是指向q所指向的结点的前驱结点。
   (3)算法
   void diff link(LinkList llist){  /*删除单链表中值相同的多余结点*/
       PNode p,q,r;    /*r总是指向q所指向的结点的前驱结点*/
       for(p=llist->link;P!=NULL;p=p->link)
       /*p从第一个结点向后扫描*/
           for(r=p,q,p->link;q!=NULL;q=q->link){
                                 /*q从p的后继结点向后扫描*/
               if(p->info==q->info){
                 r->link=q-Mink;
                 free(q);
                 q=r;
               }  /*遇到两个结点元素值相等,删除后面的结点*/
               else r=r->link;
       }
   }
   (4)代价分析
   算法中有两层循环,外层的循环次数均为O(n),内层循环次数分别为n-1,n-2,…,1。因此,本算法的时间代价为O(n2)。
【答案解析】注意两层循环内部指针a和r的用法。
   思考本算法的参数,为什么可以使用LinkList类型,而不是必须使用LinkList*类型?
   常见错误
   定义了一个带有返回值的函数LinkList diff_link(LinkList llist){…},根据参数构造了一个新的所有结点的数据值均不相同的单链表。这种做法不符合题目在原单链表中进行删除的要求。