6.递增有序链表A、B分别表示一个集合,设计算法实现A=A∩B,即使用原表空间
LinkList insert_Link_2(LinkList *A,LinkList *B){ //以带头结点的链表为例
LinkList pa=A->next;
LinkList pre=A; //pre指向pa的前驱结点
LinkList q;
LinkList pb=B->next;
while(pa!=NULL&&pb!=NULL){
if(pa->data>pb->data){ //pa所指结点更大,让pb向后移
pb=pb->next;
}
else if(pa->data<pb->data){ //pb所指结点更大,在A中删掉此结点,且pa向后移,
q=pa;
pa=pa->next; //pa后移
pre->next=pa; //pa的前驱结点的指针pre的next指针继续指向pa
free(q); //多余结点释放掉
}
else{ //当前结点属于交集,pa、pre均后移
pa=pa->next;
pre=pre->next;
}
}
if(pa!=NULL){ //pb为空,pa后的结点不可能属于A、B的交集
pa->next=NULL;
}
}
7.递增有序链表A、B分别表示一个集合,设计算法求A=A∪B
LinkList Union(LinkList *A,LinkList *B){ //将不在A中、且在B中的结点插入到A中 ,以带头结点的链表为例
LinkList pa=A->next;
LinkList pre=A; //pa的前驱结点的指针pre
LinkList pb=B->next;
LinkList r;
while(pa!=NULL&&pb!=NULL){
if(pa->data>pb->data){ //pb所指结点值小于pa,需要插入
r=pb;
pb=pb->next; //pb指针后移
r->next=pre->next; //把r插入到pa前
pre->next=r;
pre=pre->next; //pre继续指向pa前的结点
}
else if(pa->data<pb->data){ //pa所指结点的值小于pb所指结点值,pa与pre后移
pa=pa->next;
pre=pre->next;
}
else{ //pa、pb所指结点值相同,pa、pb均后移
pa=pa->next; //A、B均为集合,集合不存在相同值的结点,不应担心pb后面的结点值和pb相同,直接后移即可
pre=pre->next;
pb=pb->next;
}
}
if(pb!=NULL){ //说明pa为空,pb不为空,pb以后的结点均是A中没有的,需要插入到A的表尾
pre->next=pb;
}
return A;
}
8.已知递增有序的单链表A,B,C分别存储了一个集合,设计算法求A=A-B∩C (最后的结果是属于A但是不属于 B∩C的结点)
LinkList T_8(LinkList *A,LinkList *B,LinkList *C){ //算法思路:让A中结点和B中结点比较,若B中没有,pa移向下一个结点;
LinkList pa=A->next; //若B中有,检查C中有没有,若C中有,从A中删除此结点;若C中无此结点,pa、pb继续后移
LinkList pre=A; //pa的前驱结点的指针pre
LinkList pb=B->next;
LinkList pc=C->next;
LinkList q;
while(pa!=NULL&&pb!=NULL&&pc!=NULL){
if(pa->data<pb->data){ //B中无此结点
pa=pa->next;
pre=pre->next;
}
else if(pa->data>pb->data){
pb=pb->next;
}
else{ //此结点在B中有,需根据C的情况进行不同操作
while(pb!=NULL&&pc!=NULL){ //确定了此结点在C中有无,就要跳出这个循环
if(pb->data>pc->data){
pc=pc->next;
}
else if(pb->data<pc->data){ //C中无此结点,pa,pb后移,跳出此循环 继续比较A、B的结点
pa=pa->next;
pre=pre->next;
pb=pb->next;
break; //跳出循环
}
else{ //此结点C中也有,需要从A中删除此结点,pa,pb后移,并跳出循环,继续比较A、B中的结点
q=pa;
pre->next=pa->next;
pa=pa->next;
pb=pb->next;
free(q);
break;
}
}
}
}
return A;
}
9.设计算法将带头结点的链表A分解为两个链表A,B,是使A表含有原表奇数项结点,B含有原表偶数项结点,且保持原有相对顺序
void T_9(LinkList *A){
LinkList pa=A->next;
LinkList B=(LinkList)malloc(sizeof(LNode));
B->next=NULL; //B为带头结点的链表
LinkList r=B; //指向链表B的尾结点
int count=0; //记录当前结点序号
while(pa!=NULL){
count++;
if(count%2!=0)
pa=pa->next;
else{ //当前为偶数项,插入到B链表尾部
r->next=pa;
pa=pa->next;
r=r->next;
r->next=NULL;
}
}
}
10.设计算法将带头结点的链表A分解为两个链表A,B,使A表含有结点值为奇数,B表含有结点值为偶数,且保持原有相对顺序
void T_10(LinkList *A){
LinkList pa=A->next;
LinkList B=(LinkList)malloc(sizeof(LNode));
B->next=NULL; //B为带头结点的链表
LinkList r=B; //指向链表B的尾结点
while(pa!=NULL){
if(pa->data%2!=0)
pa=pa->next;
else{ //当前结点值为偶数,插入到B链表尾部
r->next=pa;
pa=pa->next;
r=r->next;
r->next=NULL;
}
}
}