【正确答案】(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){…},根据参数构造了一个新的所有结点的数据值均不相同的单链表。这种做法不符合题目在原单链表中进行删除的要求。