求兩個單調不減單鏈表的交集和並集(C語言)
阿新 • • 發佈:2018-11-01
一、思路:
構造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);
}
三、執行結構: