数据结构——链表例题2

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;
		}
	}
} 

 

 

 

 

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值