問題說明
求兩個線性表的並集:
La爲7、12、29、36、45
Lb爲5、18、29、36、58
兩個線性表的並集爲:
7、12、29、36、45、5、18、58
ElemType.cpp
/***
*ElemType.cpp - ElemType的實現
*
****/
#include <stdio.h>
#include "ElemType.h"
int compare(ElemType x, ElemType y)
{
return(x-y);
}
void visit(ElemType e)
{
printf("%d\t", e);
}
DynaSeqlist.cpp
/***
*DynaSeqList.cpp - 動態順序表,即順序表的動態數組實現
****/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <assert.h>
#include "DynaSeqList.h"
const int LIST_INIT_SIZE = 100; // 表初始分配的最大長度
const int LISTINCREMENT = 10; // 分配內存的增量
/*------------------------------------------------------------
操作目的: 初始化順序表
初始條件: 無
操作結果: 構造一個空的線性表
函數參數:
SqList *L 待初始化的線性表
返回值:
bool 操作是否成功
------------------------------------------------------------*/
bool InitList(SqList *L)
{
L->elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType));
if (!L->elem)
return false;
else
{
L->length = 0;
L->listsize = LIST_INIT_SIZE;
return true;
}
}
/*------------------------------------------------------------
操作目的: 銷燬順序表
初始條件: 線性表L已存在
操作結果: 銷燬線性表L
函數參數:
SqList *L 待銷燬的線性表
返回值:
無
------------------------------------------------------------*/
void DestroyList(SqList *L)
{
if (L->elem)
free(L->elem);
L->elem = NULL;
}
/*------------------------------------------------------------
操作目的: 判斷順序表是否爲空
初始條件: 線性表L已存在
操作結果: 若L爲空表,則返回true,否則返回false
函數參數:
SqList L 待判斷的線性表
返回值:
bool 是否爲空
------------------------------------------------------------*/
bool ListEmpty(SqList L)
{
if (!L.length)
return true;
else
return false;
}
/*------------------------------------------------------------
操作目的: 得到順序表的長度
初始條件: 線性表L已存在
操作結果: 返回L中數據元素的個數
函數參數:
SqList L 線性表L
返回值:
int 數據元素的個數
------------------------------------------------------------*/
int ListLength(SqList L)
{
return L.length;
}
/*------------------------------------------------------------
操作目的: 得到順序表的第i個元素
初始條件: 線性表L已存在,1<=i<=ListLength(L)
操作結果: 用e返回L中第i個數據元素的值
函數參數:
SqList L 線性表L
int i 數據元素的位置
ElemType *e 第i個數據元素的值
返回值:
bool 操作是否成功
------------------------------------------------------------*/
bool GetElem(SqList L, int i, ElemType *e)
{
if (i < 0 || i > L.length - 1)
return false;
else
*e = L.elem[i];
return true;
}
/*------------------------------------------------------------
操作目的: 得到順序表指定元素的位置
初始條件: 線性表L已存在
操作結果: 返回L中第一個與e滿足關係compare()的數據元素的位序。
若這樣的元素不存在則返回0。
函數參數:
SqList L 線性表L
ElemType e 數據元素e
int (*fp)() 用於比較相等的函數指針
返回值:
int 與e滿足關係compare()的數據元素的位序
------------------------------------------------------------*/
int LocateElem(SqList L, ElemType e, int (*fp)(ElemType, ElemType))
{
for (int i = 0; i < L.length; i++)
{
if(!(*fp)(e,L.elem[i]))
return i;
}
return 0;
}
/*------------------------------------------------------------
操作目的: 得到順序表指定元素的前驅
初始條件: 線性表L已存在
操作結果: 若cur_e是L的數據元素,且不是第一個,則用pre_e返回
它的前驅,否則操作失敗,pre_e無定義
函數參數:
SqList L 線性表L
ElemType cur_e 數據元素cur_e
ElemType *pre_e 前驅數據元素
返回值:
bool 操作是否成功
------------------------------------------------------------*/
bool PriorElem(SqList L, ElemType cur_e, ElemType *pre_e)
{
int i = LocateElem(L, cur_e, compare);
if (i>=0 && i!= 1)
{
*pre_e = L.elem[i - 1];
return true;
}
return false;
}
/*------------------------------------------------------------
操作目的: 得到順序表指定元素的後繼
初始條件: 線性表L已存在
操作結果: 若cur_e是L的數據元素,且不是最後一個,則用nxt_e返
回它的後繼,否則操作失敗,nxt_e無定義
函數參數:
SqList L 線性表L
ElemType cur_e 數據元素cur_e
ElemType *nxt_e 後繼數據元素
返回值:
bool 操作是否成功
------------------------------------------------------------*/
bool NextElem(SqList L, ElemType cur_e, ElemType *nxt_e)
{
int i = LocateElem(L, cur_e, compare);
if (i>=0 && i != L.length - 1)
{
*nxt_e = L.elem[i + 1];
return true;
}
return false;
}
/*------------------------------------------------------------
操作目的: 遍歷順序表
初始條件: 線性表L已存在
操作結果: 依次對L的每個元素調用函數fp
函數參數:
SqList L 線性表L
void (*fp)() 訪問每個數據元素的函數指針
返回值:
無
------------------------------------------------------------*/
void ListTraverse(SqList L, void (*fp)(ElemType))
{
for (int i = 0; i < L.length; i++)
(*fp)(L.elem[i]);
printf("\n");
}
/*------------------------------------------------------------
操作目的: 清空順序表
初始條件: 線性表L已存在
操作結果: 將L置爲空表
函數參數:
SqList *L 線性表L
返回值:
無
------------------------------------------------------------*/
void ClearList(SqList *L)
{
L->length = 0;
}
/*------------------------------------------------------------
操作目的: 在順序表的指定位置插入結點,插入位置i表示在第i個
元素之前插入
初始條件: 線性表L已存在,1<=i<=ListLength(L) + 1
操作結果: 在L中第i個位置之前插入新的數據元素e,L的長度加1
函數參數:
SqList *L 線性表L
int i 插入位置
ElemType e 待插入的數據元素
返回值:
bool 操作是否成功
------------------------------------------------------------*/
bool ListInsert(SqList *L, int i, ElemType e)
{
ElemType* newbase = NULL;
if (i < 0 || i>L->length)
return false;
if (L->length == L->listsize)
{
newbase = (ElemType*)realloc(L->elem, (LIST_INIT_SIZE + LISTINCREMENT) * sizeof(ElemType));
if (!newbase)
return false;
else
{
L->elem = newbase;
L->listsize += LISTINCREMENT;
}
}
for (int j = L->length; j > i; j--)
L->elem[j] = L->elem[j - 1];
L->elem[i] = e;
++L->length;
return true;
}
/*------------------------------------------------------------
操作目的: 在順序表的指定位置插入結點,插入位置i表示在第i個
元素之前插入
初始條件: 線性表L已存在,1<=i<=ListLength(L) + 1
操作結果: 在L中第i個位置之前插入新的數據元素e,L的長度加1
函數參數:
SqList *L 線性表L
int i 插入位置
ElemType e 待插入的數據元素
返回值:
bool 操作是否成功
------------------------------------------------------------*/
void HeadInsert(SqList* L, ElemType e) //線性表的頭插法
{
ListInsert(L, 0, e);
}
/*------------------------------------------------------------
操作目的: 在順序表的指定位置插入結點,插入位置i表示在第i個
元素之前插入
初始條件: 線性表L已存在,1<=i<=ListLength(L) + 1
操作結果: 在L中第i個位置之前插入新的數據元素e,L的長度加1
函數參數:
SqList *L 線性表L
int i 插入位置
ElemType e 待插入的數據元素
返回值:
bool 操作是否成功
------------------------------------------------------------*/
void TailInsert(SqList* L, ElemType e) //線性表的尾插法
{
ListInsert(L, L->length, e);
}
/*------------------------------------------------------------
操作目的: 刪除順序表的第i個結點
初始條件: 線性表L已存在且非空,1<=i<=ListLength(L)
操作結果: 刪除L的第i個數據元素,並用e返回其值,L的長度減1
函數參數:
SqList *L 線性表L
int i 刪除位置
ElemType *e 被刪除的數據元素值
返回值:
bool 操作是否成功
------------------------------------------------------------*/
bool ListDelete(SqList* L, int i, ElemType* e)
{
if (i < 0 || i>L->length - 1)
return false;
*e = L->elem[i];
for (int j = i; j < L->length - 1; j++)
{
L->elem[j] = L->elem[j + 1];
}
--L->length;
return true;
}
void ListDeleteHead(SqList* L, ElemType* e) //線性表的頭刪法
{
ListDelete(L,0, e);
}
void ListDeleteTail(SqList* L, ElemType* e) //線性表的尾刪法
{
*e = L->elem[L->length - 1];
L->length--;
}
/*------------------------------------------------------------
操作目的: 求兩個線性表的並集
初始條件: 兩個線性表La 和 Lb 都已存在且非空,1<=i<=ListLength(La) 1<=i<=ListLength(Lb)
操作結果: 打印連接之後的線性表
函數參數:
SqList* La, SqList* Lb 求並集的兩個線性表
返回值:
void 不需要返回值
------------------------------------------------------------*/
void unionList(SqList* La, SqList Lb)
{
int La_len = ListLength(*La);
int Lb_len = ListLength(Lb);
ElemType e = 0;
for (int i = 0; i < Lb_len; i++)
{
GetElem(Lb, i, &e); // 取 Lb 中第 i 個數據元素賦給 e
if (!LocateElem(*La, e, compare)) //如果e和線性表 La 的所有元素都不想等
ListInsert(La, La->length, e); //把 e 插入到La的尾部
else
continue;
}
}
DynaSeqlist.h
/***
*
DynaSeqList.h - 動態順序表的定義
*
****/
#if !defined(DYNASEQLIST_H)
#define DYNASEQLIST_H
#include "ElemType.h"
/*------------------------------------------------------------
順序表結構的定義
------------------------------------------------------------*/
typedef struct List
{
ElemType *elem; // 存儲空間的基址
int length; // 順序表中結點元素的個數
int listsize; // 順序表的存儲空間大小
} SqList;
/*------------------------------------------------------------
// 順序表的基本操作
------------------------------------------------------------*/
bool InitList(SqList *L); //線性表初始化
void DestroyList(SqList *L); //線性表銷燬
bool ListEmpty(SqList L); //線性表判空
int ListLength(SqList L); //線性表長度
bool GetElem(SqList L, int i, ElemType *e); //獲得下標 i 的數據元素
int LocateElem(SqList L, ElemType e, int (*fp)(ElemType, ElemType));//獲得和元素e有關的元素
bool PriorElem(SqList L, ElemType cur_e, ElemType *pre_e); //獲得數據元素的前驅
bool NextElem(SqList L, ElemType cur_e, ElemType *nxt_e); //獲得數據元素的後繼
void ListTraverse(SqList L, void (*fp)(ElemType)); //遍歷線性表
void ClearList(SqList *L); //清空線性表
bool ListInsert(SqList* L, int i, ElemType e); //在 i 位置插入數據元素
void HeadInsert(SqList* L, ElemType e); //線性表的頭部插入元素
void TailInsert(SqList* L, ElemType e); //線性表的尾部插入元素
bool ListDelete(SqList *L, int i, ElemType *e); //刪除 i 位置的數據元素
void ListDeleteHead(SqList* L,ElemType* e); //刪除線性表的頭部元素
void ListDeleteTail(SqList* L,ElemType* e); //刪除線性表的尾部元素
void unionList(SqList* La, SqList Lb); //求兩個線性表的並集
#endif /* DYNASEQLIST_H */
ElemType.h
/***
*ElemType.h - ElemType的定義
*
****/
#ifndef ELEMTYPE_H
#define ELEMTYPE_H
typedef int ElemType; //定義數據類型
int compare(ElemType x, ElemType y); //聲明判斷函數
void visit(ElemType e); //聲明打印函數
#endif /* ELEMTYPE_H */
# Lab.cpp
#include <stdio.h>
#include "DynaSeqList.h"
int main()
{
SqList La, Lb;
if (InitList(&La))
printf("初始化成功\n");
else
printf("初始化失敗\n");
if (InitList(&Lb))
printf("初始化成功\n");
else
printf("初始化失敗\n");
ListInsert(&La, 0, 45);
ListInsert(&La, 0, 36);
ListInsert(&La, 0, 29);
ListInsert(&La, 0, 12);
ListInsert(&La, 0, 7);
printf("線性表La的值爲:\n");
ListTraverse(La,visit);
ListInsert(&Lb, 0, 5);
ListInsert(&Lb, 1, 18);
ListInsert(&Lb, 2, 29);
ListInsert(&Lb, 3, 36);
ListInsert(&Lb, 4, 58);
printf("線性表Lb的值爲:\n");
ListTraverse(Lb, visit);
unionList(&La, Lb);
printf("La和Lb的並集爲:\n");
ListTraverse(La, visit);
DestroyList(&La);
DestroyList(&Lb);
return 0;
}