二、集合合并
二、集合合并
文章目錄
- 二、集合合并
- 題目描述
- 解題思路
- 上機代碼
- 簡單拓展
題目描述
我們的教材上討論了一個如何使用基本運算將兩個集合合并的問題。下面,我們就采用基本操作完成集合合并的操作。
問題: 線性表的合并A=A∪B
設:有兩個集合A和B分別用兩個線性表LA和LB表示。求一個新的集合 A=A∪B。
- 輸入:兩個集合
- 輸出:按照要求合并后的集合。
編程要求:題目中已經給出了主函數和部分已經實現的基本操作,請閱讀給出的程序,編寫其他尚未完成的基本操作(基本操作的定義請參見教材)。
注意:提交代碼的時候,僅需提交你編寫的那三個基本操作函數即可。
前置代碼:
/* PRESET CODE BEGIN - NEVER TOUCH CODE BELOW */#include <stdio.h> #include <stdlib.h> #define LIST_MAX_SIZE 100 //空間初始大小 #define OK 1 #define ERROR 0typedef int ElemType; //元素的數據類型 typedef int Status; //狀態。函數返回值 typedef struct { // ElemType elem[ LIST_MAX_SIZE ]; // 存儲空間ElemType * elem; // 存儲空間int length; // 當前元素個數int listsize; // 能夠保存的最大元素數量 } SqList;// 以下為函數原型 Status InitList( SqList & ); Status ListInsert( SqList &, int, ElemType ); //這是需要你編寫的基本操作 Status GetElem( SqList, int, ElemType & ); //這是需要你編寫的基本操作 int ListLength( SqList ); //這是需要你編寫的基本操作 Status ListTraverse( SqList &, void (*)( ElemType ) ); void ListUnion( SqList &, SqList ); void out( ElemType ); int equal(ElemType, ElemType ); Status LocateElem(SqList, ElemType, Status (*)(ElemType,ElemType));// 以下為函數定義 Status InitList( SqList & L ) // 建立一個空的線性表 L {L.elem = (ElemType *)malloc(LIST_MAX_SIZE*sizeof(ElemType)); // if ( !L.elem ) exit(-1); // 失敗則終止程序 L.length = 0; // 空表長度為0L.listsize = LIST_MAX_SIZE;return OK; }Status ListTraverse( SqList &L, void (*visit)( ElemType ) ) { // 依次對L的每個元素調用函數visit()。若visit()失敗,則操作失敗int i, L_len = ListLength( L );ElemType e;for ( i = 1; i <= L_len; i++ ) {GetElem(L, i, e);(*visit)( e );}return OK; }int equal(ElemType x, ElemType y) { return x==y; }Status LocateElem( SqList L, ElemType e,Status (*compare)(ElemType,ElemType) ) { //在L中查找與元素 e 滿足compare() 的第 1 個元素//返回 L 中第 1 個與 e 滿足關系compare( ) 的元素的位序int i = 1;ElemType * p;while ( i<=L.length ) //if ( (*compare)(e,L.elem[i-1]) ) break;else i++;if ( i <= L.length ) return i; // 找到 e,返回位序ielse return 0; //若沒有找到,則返回0 }void out( ElemType e ) { printf("%d,", e); }void ListUnion( SqList &La, SqList Lb ) //求 A=A∪B { int La_len, Lb_len, i;ElemType e;La_len = ListLength( La ); // 求線性表的長度Lb_len = ListLength( Lb );for ( i = 1; i <= Lb_len; i++ ) {GetElem(Lb, i, e); // 取Lb中第i個數據元素賦給eif ( !LocateElem( La, e, equal ) ) ListInsert ( La, ++La_len, e ); // La中不存在和 e 相同的數據元素,則插入} }int main() { SqList La, Lb;int n, i;ElemType e;InitList( La );InitList( Lb );scanf("%d", &n); //讀入集合A for ( i=0; i<n; i++ ){ scanf("%d", &e);ListInsert( La, i+1, e );}scanf("%d", &n); //讀入集合B for ( i=0; i<n; i++ ){ scanf("%d", &e);ListInsert( Lb, i+1, e );}printf("Output La:");ListTraverse( La, out );printf("\nOutput Lb:");ListTraverse( Lb, out );ListUnion( La, Lb );printf("\nResult La:");ListTraverse( La, out );printf("\n");return OK; }/**************** Status ListInsert( SqList &L, int i, ElemType e ) { //在順序線性表L中第 i (1≤i≤L.length+1)個位置之前插入元素e,Here is wating for you.}Status GetElem(SqList L, int i, ElemType &e) {Here is wating for you.}int ListLength(SqList L) { Here is wating for you.} *********************//* PRESET CODE END - NEVER TOUCH CODE ABOVE */| 測試用例 1 | 5 1 2 3 4 5 6 3 4 5 6 7 8 | Output La:1,2,3,4,5, Output Lb:3,4,5,6,7,8, Result La:1,2,3,4,5,6,7,8,? | 1秒 | 64M | 0 |
| 測試用例 2 | 0 4 1 2 3 4 | Output La: Output Lb:1,2,3,4, Result La:1,2,3,4,? | 1秒 | 64M | 0 |
| 測試用例 3 | 5 8 9 0 1 2 6 8 9 0 3 2 1? | Output La:8,9,0,1,2, ?Output Lb:8,9,0,3,2,1, Result La:8,9,0,1,2,3,? | 1秒 | 64M | 0 |
解題思路
| 插入元素-ListInsert() | 在順序線性表L中第 i (1≤i≤L.length+1)個位置之前插入元素e。 若i的輸入不合法,或者存儲空間已滿,則返回ERROR,表示插入失敗; 否則,在表尾插入新元素e,順序表長度增加1,插入成功,返回OK |
| 按位查找-GetElem() | 獲取線性表L中第 i 個位置的元素的值。 若i的輸入不合法,則返回ERROR,表示獲取失敗; 否則,根據線性表隨機存取的特點,獲取表中物理結構第i-1個位置的值,返回OK |
| 求表長-ListLength() | 直接返回線性表L的長度即可 |
上機代碼
Status ListInsert( SqList &L, int i, ElemType e ) {if (i<1 || i>L.length+1)//判斷i的范圍是否有效{return ERROR;}if (L.length>=L.listsize)//判斷存儲空間是否已滿{return ERROR;}L.elem[L.length] = e;//表尾插入新元素L.length++;return OK; }Status GetElem(SqList L, int i, ElemType &e) {if (i<1 || i>L.length)//判斷i的范圍是否有效{return ERROR;}e = L.elem[i-1];//獲取第i個位置的值return OK; }int ListLength(SqList L) { return L.length;//獲取線性表的長度 }簡單拓展
這個題在 ListInsert() 插入操作時是直接通過表尾進行插入,但是對于更一般的線性表插入操作,應當為指定任意位置i進行插入。
對于任意指定位置i,將順序表的第i個元素及其后的所有元素右移一個位置,騰出一個空位置插入新元素e,順序表長度加1,插入成功,返回OK。
Status ListInsert( SqList &L, int i, ElemType e ) {if (i<1 || i>L.length+1)//判斷i的范圍是否有效{return ERROR;}if (L.length>=L.listsize)//判斷存儲空間是否已滿{return ERROR;}for (int j = L.length; j >= i; j--)//將對應元素后移{L.elem[j] = L.elem[j-1];}L.elem[i-1] = e;//位置i處插入eL.length++;return OK; }總結