在带头结点的单链表L中,删除所有值为x的结点,并释放其空间,假设值为x的结点不唯一,试编写算法以实现上述操作。
解法一:用p从头至尾扫描单链表,pre指向*p结点的前驱。若p所指结点的值为x,则删除,并让p移向下一个结点,否则让pre、p指针同步后移一个结点。
本题代码如下:
- void Del_X_1(Linklist &L, ElemType x){
- //L为带头的单链表,本算法删除L中所有值为x的结点
- LNode *p=L->next, *pre=L, *q; //置 p 和 pre 的初始值
- while(p!=NULL){
- if(p->data==x){
- q=p; //q指向该结点
- p=p->next;
- pre->next=p; //删除*q 结点
- free(q); //释放 *q结点的空间
- }else{ //否则,pre和p同步后移
- pre=p;
- p=p->next;
- } //else
- } //while
- }
本算法是在无序单链表中删除满足某种条件的所有结点,这里的条件是结点的值为x。实际上,这个条件是可以任意指定的,只要修改if条件即可,比如,我们要求删除值介于 mink和maxk之间的所有结点,则只需将if语句修改为if(p->data>mink &&p->data<maxk)。
解法二:用尾插法建立单链表。用p指针扫描L的所有结点,当其值不为x时将其链接到L之后,否则将其释放。
本题代码如下:
- void Del_X_2(Linklist &L, ElemType x){
- //L为带头的单链表,本算法删除L中所有值为x的结点
- LNode *p=3->next, *r=L, *q; //r指向尾结点,其切值为头结点
- while(p!=NULL){
- if (p->data!=x) { //*p结点值不为x时将其链接到L尾部
- r->next=p;
- r=p;
- p=p->next; //继续扫描
- }else{ //*p结点值为x时将其释放
- q=p;
- p=p->next; //继续扫描
- free(q); //释放空间
- }
- }//while
- r->next=NULL; //插入结束后置尾结点指针为NULL
- }
上述两个算法扫描一遍链表,时间复杂度为O(n),空间复杂度为O(1)。