1. 程式人生 > >求兩個單調不減單鏈表的交集和並集(C語言)

求兩個單調不減單鏈表的交集和並集(C語言)

一、思路:

構造struct node* Link(struct node *P,struct node *Q,int sign)函式,當sign=1時,返回P,Q的並集,當sign=0時,返回P,Q的交集,求交併的思路為:

①對P,Q分別賦予兩個指標p和q,初始時分別指向P,Q的頭結點

建立兩個空連結串列U(Union)和I(Intersection),用於存P,Q的並集與交集,同樣賦予兩個初始指向它們頭的指標u和i

②判斷p,q的值,將值小的插入並集U連結串列的後面,即u的後面,並且u指向下一位,同時這個節點也向後移一位;

若p,q值相同,則將此節點插入交集I和並集U連結串列的後面,即i和u的後面,並且i和u指向下一位,同時p,q都向後移一位;

並且,對於單調不減的函式,存在有相同值的節點的情況,故每次移位前都判斷一下,下一位是否跟此位的值相同,若是,則再向後移一位。

一直迴圈上述,直至p,或q為空

③可能存在三種情況:

1)p空,q空,則全部遍歷並插入完畢

2)p空,q非空,則將q後剩餘節點全部插入並集U

3)p非空,q空,同理,則將p後剩餘節點全部插入並集U

④根據sign值返回U或I

二、程式碼:

(我將單鏈表的結構與構造P,Q均放在了Node.h中)

單鏈表的結構為:

 struct  node{  
    int value; 
    struct node *next;  
};

構造P,Q():

/*建立連結串列P*/  
struct node *creatL1(void){  
    struct node *p1,*p2,*p3,*p4,*p5,*p6,*p7;  
    p1=(struct node *)malloc(LEN);  
    p2=(struct node *)malloc(LEN);  
    p3=(struct node *)malloc(LEN); 
    p4=(struct node *)malloc(LEN);  
    p5=(struct node *)malloc(LEN);
    p6=(struct node *)malloc(LEN);  
    p7=(struct node *)malloc(LEN); 
    
    p1->value = 1;  
    p2->value = 3; 
    p3->value = 6; 
    p4->value = 6; 
    p5->value = 6; 
    p6->value = 13; 
    p7->value = 15; 
    
    p1->next = p2;  
    p2->next = p3;  
    p3->next = p4;
	p4->next = p5;
	p5->next = p6;
	p6->next = p7;
	p7->next = NULL;
    return(p1);  
}
/*建立連結串列Q*/
struct node *creatL2(void){  
    struct node *p1,*p2,*p3,*p4,*p5,*p6;  
    p1=(struct node *)malloc(LEN);  
    p2=(struct node *)malloc(LEN);  
    p3=(struct node *)malloc(LEN); 
    p4=(struct node *)malloc(LEN);  
    p5=(struct node *)malloc(LEN);  
	p6=(struct node *)malloc(LEN); 
 
    p1->value = 2;  
    p2->value = 3; 
    p3->value = 6; 
    p4->value = 8; 
    p5->value = 15;
	p6->value = 17; 
    
    p1->next = p2;  
    p2->next = p3;  
    p3->next = p4;
	p4->next = p5;
	p5->next = p6;
	p6->next = NULL;
    return(p1);  
}

主函式:

#include<stdio.h>  
#include"Node.h"
#define LEN sizeof(struct node)
int main(){ 
	struct node* Link(struct node *P,struct node *Q,int sign);
	void Print(struct node *P);
	struct node *I,*U;
	
	//輸出一下P,Q情況
	printf("P為:\n");
	Print(creatL1());
	printf("Q為:\n");
	Print(creatL2());
	
	U=Link(creatL1(),creatL2(),1);
	I=Link(creatL1(),creatL2(),0);
	
		
	//輸出交集並集 
	printf("P,Q的並集為:\n");
	Print(U->next);
	printf("P,Q的交集為:\n");
	Print(I->next);
    
  
}
struct	node* Link(struct node *P,struct node *Q,int sign){
	struct node *u,*U,*i,*I;
	struct node *p=P,*q=Q;
	u = U=(struct node *)malloc(LEN);
	i = I=(struct node *)malloc(LEN);
	//②步驟,迴圈插入 
	while(p!=NULL && q!=NULL){
		if(p->value > q->value){
			u->next = q;
			u = u->next;
			while(q->next!=NULL && q->next->value == q->value)//過濾掉相等的節點 
				q = q->next;
			q = q->next;


		}else if(p->value < q->value){
			u->next = p;
			u = u->next;
			while(p->next!=NULL && p->next->value == p->value)
				p = p->next;
			p = p->next;
		}
		else if(p->value == q->value){
			i->next = q;
			u->next = p;
			i = i->next;
			u = u->next;


			while(q->next!=NULL && q->next->value == q->value)
				q = q->next;
			while(p->next!=NULL && p->next->value == p->value)
				p = p->next;
			q = q->next;
			p = p->next;
		
		}
	}
	i->next = NULL;
	//③步驟 ,處理剩餘 
	if(q!=NULL)
		u->next = q;
	else if(p!=NULL)
		u->next = p;
		
	if(sign ==1)
		return U;
	else if(sign == 0)
		return I;
}
//列印輸出一個連結串列的全部資料 
void Print(struct node *P){
	struct node *p = P;
	while(p->next!=NULL){
    	printf("%d->",p->value);
    	p = p->next;
    }
    printf("%d\n",p->value);
} 

三、執行結構: