【例1】有一个递增非空单链表,设计一个算法删除值域重复的结点。例如,{1,1,2,3,3,3,4,4,7,7,7,9,9,9} 经过删除后变成 {1,2,3,4,7,9}
/* 思路:p,q指针一前一后,紧密相连。若两指针所指的data相同,则删除q所指的结点,然后一前一后继续遍历 */
void delete(LNode *L){
LNode *p,*q,*s;
p=L->next;
q=p->next;
while(q!=NULL){
if(p->data==q->data){
s=q;
p->next=q->next;
q=q->next;
free(s);
}
else{
p=q;
q=q->next;
}
}
}
【例2】设计一个算法删除单链表 L (有头结点)中的一个最小值结点。
/* 思路:假设单链表中第一个值为最小值,并用指针 r 指向,并用 s 指针指向它的前驱结点
再定义两个指针 p,q ,一前一后紧密相连,用来遍历单链表
遍历的同时比较 q 所指向的值与 r 所指向的值的大小,若更小,则更新 r 指针以及 s指针 */
void deleteMin(LNode *L){
LNode *s,*r,*p,*q;
s=L;
r=L->next;
p=L->next;
q=p->next;
while(q!=NULL){
if(q->data < r->data){
r=q;
s=p;
}
p=q;
q=q->next;
}
r->next=s->next;
free(s);
}
【例3】有一个线性表,采用带头结点的单链表L来存储。设计一个算法将其逆置。要求不能建立新结点,只能通过表中已有结点的重新组合来完成。
/* 思路:这里可以将L中的元素作为逆转后L的元素来源,即将L->next 设置为空,
然后将头结点后的一串结点用头插法逐个插入L中,这样新的L中的元素顺序正好是逆序的。 */
void reverse(LNode *L){
LNode *p,*q;
p=L->next;
L->next=NULL;
while(p!=NULL){
q=p->next;
p->next=L->next;
L->next=p;
p=q;
}
}
【例4】设计一个算法,将一个头结点为A的单链表(其数据域为整数〉分解成两个单链表A和B,使得A链表只含有原来链表中 data域为奇数的结点,而B链表只含有原链表中 data域为偶数的结点,且保持原来的相对顺序。
/* 思路:对A而言是删除data为偶数的结点,对B而言是采用尾插法增加那些被A删除的结点。 */
void split2(LNode *A,LNode *&B){
B=(LNode*)malloc(sizeof(LNode));
B->next=NULL;
LNode *p,*q,*r,*s;
p=A;
q=A->next;
r=B;
while(q!=NULL){
if(q->data%2==0){
//偶数时,A删 B增
s=q; //提前把即将被删除的结点保留,便于后续在B中添加
p->next=q->next; //将偶数从A中删除
q=p->next;
s->next=NULL; //这一句必须写,将其变成一个没有后续的结点
r->next=s;
r=s;
}
else{
//奇数时,A继续遍历
p=q;
q=q->next;
};
}
}