解題思路(單鏈表求交集、並集、差集的思想和順序表求交集、並集、差集的思想基本相同)
1.先通過CreateListR 函數將集合 a 和 b 中的元素添加到順序表 ha 和 hb 中 ,添加過程使用的是順序表原有的Initlist 函數(初始化表) 和 ListInsert 函數 (向表中插入元素) 。
2.因為原集合是無序的, 所以我通過 sort 函數 (選擇排序),使得集合變得有序。
3.得到有序集合 ha 和 hb 后, 便可以使用 Union 函數(類似歸並的思想寫出來的求並集的函數),求出 ha 和 hb 的並集。
4.而求交集的方法則是, 通過將 集合 a 中的元素一個一個取出,並通過 函數LocateElem ,查看集合 hb 中是否存在該元素,如果存在則將 元素放入 hc ,如果不存在,則舍去。 以此求得 兩 集合的交集。
5.求兩集合的差 則可以反過來,同樣通過將 集合 a 中的元素一個一個取出,並通過 函數LocateElem ,查看集合 hb 中是否存在該元素,如果不存在則將 元素放入 hc ,如果存在,則舍去。 以此求得兩集合的差集。
#include <iostream> #include <cstdio> #include <malloc.h> using namespace std; /* 定義單鏈表數據 */ typedef char ElemType; typedef struct LNode { ElemType data; struct LNode *next; }LinkList; /* 單鏈表的初始化 */ void InitList(LinkList *&L) { L = (LinkList *)malloc(sizeof(LinkList)); L->next=NULL; } /* 向單鏈表中插入數據元素 */ bool ListInsert(LinkList *&L,int x,char e) { int j = 0; LinkList *p = L, *s; while(p!=NULL && j<x-1) { p = p->next; j++; } if(p==NULL) { return false; } else { s = (LinkList *)malloc(sizeof(LinkList)); s->data = e; s->next = p->next; p->next = s; return true; } } /* 輸出單鏈表 */ void DispList(LinkList *L) { LinkList *p = L->next; while(p!=NULL) { printf("%c ",p->data); p = p->next; } printf("\n"); } /* 求單鏈表的長度 */ int ListLength(LinkList *L) { LinkList *p = L->next; int i = 0; while(p!=NULL) { i++; p = p->next; } return i; } /* 查看單鏈表是否為空 */ bool ListEmpty(LinkList *L) { return L->next==NULL; } /* 求單鏈表中某個數據元素值 */ bool GetElem(LinkList *L,int i, ElemType &e) { LinkList *p = L; int j = 0; while(p!=NULL && j < i) { p=p->next; j++; } if(p==NULL) { return false; } else { e = p->data; return true; } } /* 在單鏈表中查找元素 */ int LocateElem(LinkList *L,ElemType e) { LinkList *p = L; int i = 0; while(p!=NULL && p->data!=e) { p = p->next; i++; } if(p==NULL) { return 0; } else { return i; } } /* 刪除單鏈表中第 i 個元素*/ bool ListDelete(LinkList *&L,int i,ElemType &e) { int j = 0; LinkList *p = L, *q; while(p!=NULL && j < i - 1) { p = p->next; j++; } if(p==NULL) return false; else { q = p->next; if(q==NULL) return false; e = q->data; p->next = q->next; free(q); return true; } } /* 刪除單鏈表 */ void DestroyList(LinkList *&L) { LinkList *p = L; LinkList *q = p->next; while(q!=NULL) { free(p); p = q; q = p->next; } free(p); } void CreateListR(LinkList *&L,ElemType e[],int n) { InitList(L); int i; for(i = 0;i < n; ++i) { if(!LocateElem(L,e[i])) ListInsert(L,i+1,e[i]); } } void InsterSect(LinkList *a,LinkList *b,LinkList *&c) { DestroyList(c); InitList(c); LinkList *p = a->next; int i = 0; while(p!=NULL) { if(LocateElem(b,p->data)) ListInsert(c,++i,p->data); p = p->next; } } void Subs(LinkList *a,LinkList *b,LinkList *&c) { DestroyList(c); InitList(c); LinkList *p = a->next; int i = 0; while(p!=NULL) { if(!LocateElem(b,p->data)) ListInsert(c,++i,p->data); p = p->next; } } void Union(LinkList *a,LinkList *b,LinkList *&c) { InitList(c); LinkList *p = a->next; LinkList *q = b->next; int k = 0; while(p!=NULL && q!=NULL) { if(p->data < q->data) { ListInsert(c,k+1,p->data); p = p->next; k++; } else if(p->data == q->data) { ListInsert(c,k+1,p->data); p = p->next; q = q->next; k++; } else { ListInsert(c,k+1,q->data); q = q->next; k++; } } while(p!=NULL) { ListInsert(c,k+1,p->data); p = p->next; k++; } while(q!=NULL) { ListInsert(c,k+1,q->data); q = q->next; k++; } ///cout<<"hehe"<<endl; } void sort(LinkList *&L) { LinkList *p , *pre, *q, *k; InitList(p); int i = 0; char c; while(!ListEmpty(L)) { pre = L ->next; c = pre->data; while(pre!=NULL) { if(c>=pre->data) c = pre->data; pre = pre->next; } ListInsert(p,++i,c); int tag = LocateElem(L,c); ListDelete(L,tag,c); } L = p; } int main( ) { LinkList *ha, *hb, *hc; ElemType a[]={'c','a','e','h'}; ElemType b[]={'f','h','b','g','d','a'}; printf("集合的運算如下\n"); CreateListR(ha,a,4); CreateListR(hb,b,6); printf("原 集 合 A: "); DispList(ha); printf("原 集 合 B: "); DispList(hb); sort(ha); sort(hb); printf("有序集合A:"); DispList(ha); printf("有序集合B:"); DispList(hb); Union(ha,hb,hc); printf("集合的並C:"); DispList(hc); InsterSect(ha,hb,hc); printf("集合的交C:"); DispList(hc); Subs(ha,hb,hc); printf("集合的差C:"); DispList(hc); DestroyList(ha); DestroyList(hb); DestroyList(hc); return 0; }
