#include "SqList.h"
void UnionList(SqList* La, SqList* Lb)
{
int La_len = ListLength(La);
int Lb_len = ListLength(Lb);
ElemType data1;
ElemType data2;
for (int i = 1; i <= Lb_len; i++)
{
int judge = 0;
data2 = GetElem(Lb, i);
for (int j = 1; j <= La_len; j++)
{
data1 = GetElem(La, j);
if (data1 == data2)
{
judge = 1;
break;
}
}
if (judge == 0)
ListInsertTail(La, data2);
}
}
int main()
{
SqList La, Lb;
if (InitList(&La))
printf("初始化成功\n");
else
printf("初始化失败\n");
if (InitList(&Lb))
printf("初始化成功\n");
else
printf("初始化失败\n");
ListInsert(&La, 1, 10);
ListInsert(&La, 1, 20);
ListInsert(&La, 1, 30);
ListInsert(&La, 1, 40);
printf("La当前的线性表是:");
ListTraverse(&La);
ListInsert(&Lb, 1, 10);
ListInsert(&Lb, 1, 20);
ListInsert(&Lb, 1, 40);
ListInsert(&Lb, 1, 80);
printf("Lb当前的线性表是:");
ListTraverse(&Lb);
UnionList(&La, &Lb);
printf("La当前的线性表是:");
ListTraverse(&La);
return 0;
}
#include "SqList.h"
const int LIST_INIT_SIZE = 10; // 表初始分配的最大长度
/*------------------------------------------------------------
操作目的: 初始化顺序表
初始条件: 无
操作结果: 构造一个空的线性表
函数参数:
sqListPtr L 待初始化的线性表
返回值:
bool 操作是否成功
------------------------------------------------------------*/
bool InitList(sqListPtr L)
{
assert(L != NULL); //断言L不为空,如果L为空则所有操作都没有意义
if (L == NULL) //如果L为空
{
printf("%d\t %s error", __LINE__, __FILE__); //打印出错的文件和代码行数便于修改
exit(0);
}
L->elem = (ElemType*)malloc(LIST_INIT_SIZE * sizeof(ElemType)); //动态申请10个空间
if ( NULL == L->elem )
{
printf("apply fail\n");
return false;
}
else
{
L->length = 0;
L->listsize = LIST_INIT_SIZE;
return true;
}
}
/*------------------------------------------------------------
操作目的: 销毁顺序表
初始条件: 线性表L已存在
操作结果: 销毁线性表L
函数参数:
sqListPtr L 待销毁的线性表
返回值:
无
------------------------------------------------------------*/
void DestroyList(sqListPtr L)
{
assert(L != NULL); //断言L不为空,如果L为空则所有操作都没有意义
if (L == NULL) //如果L为空
{
printf("%d\t %s error", __LINE__, __FILE__); //打印出错的文件和代码行数便于修改
exit(0);
}
free(L->elem);
L->elem = NULL;
}
/*------------------------------------------------------------
操作目的: 判断顺序表是否为空
初始条件: 线性表L已存在
操作结果: 若L为空表,则返回true,否则返回false
函数参数:
sqListPtr L 待判断的线性表
返回值:
bool 是否为空
------------------------------------------------------------*/
bool ListEmpty(sqListPtr L)
{
assert(L != NULL);
if (L == NULL)
{
printf("%d\t %s error", __LINE__, __FILE__);
exit(0);
}
if (0 == L->length )
return true;
else
return false;
}
/*------------------------------------------------------------
操作目的: 得到顺序表的长度
初始条件: 线性表L已存在
操作结果: 返回L中数据元素的个数
函数参数:
sqListPtr L 线性表L
返回值:
int 数据元素的个数
------------------------------------------------------------*/
int ListLength(sqListPtr L)
{
assert(L != NULL);
if (L == NULL)
{
printf("%d\t %s error", __LINE__, __FILE__);
exit(0);
}
return L->length;
}
/*------------------------------------------------------------
操作目的: 返回顺序表的第i个元素
初始条件: 线性表L已存在,1<=i<=ListLength(L)
操作结果: 用e返回L中第i个数据元素的值
函数参数:
sqListPtr L线性表L
int i 数据元素的位置
返回值:
顺序表的第i个元素
------------------------------------------------------------*/
int GetElem(sqListPtr L, int i)
{
assert(L != NULL); //断言L不为空,如果L为空则所有操作都没有意义
if (L == NULL) //如果L为空
{
printf("%d\t %s error", __LINE__, __FILE__); //打印出错的文件和代码行数便于修改
exit(0);
}
if (i < 1 || i > L->length)
{
printf("pos error\n");
exit(0);
}
return L->elem[i - 1];
}
/*------------------------------------------------------------
操作目的: 得到顺序表指定元素的前驱
初始条件: 线性表L已存在
操作结果: 返回前驱的值
函数参数:
SqList L 线性表L
当前位置i
返回值:
int 返回前驱元素的值
------------------------------------------------------------*/
int PriorElem(sqListPtr L,int i)
{
assert(L != NULL); //断言L不为空,如果L为空则所有操作都没有意义
if (L == NULL) //如果L为空
{
printf("%d\t %s error", __LINE__, __FILE__); //打印出错的文件和代码行数便于修改
exit(0);
}
if (0 != i && 1 != i)
return L->elem[i - 2];
return 0;
}
/*------------------------------------------------------------
操作目的: 得到顺序表指定元素的后继
初始条件: 线性表L已存在
操作结果: 返回i位置的后继值
函数参数:
SqList L 线性表L
当前操作的顺序表位置i
返回值:
int 返回后继元素的值
------------------------------------------------------------*/
int NextElem(sqListPtr L, int i)
{
assert(L != NULL); //断言L不为空,如果L为空则所有操作都没有意义
if (L == NULL) //如果L为空
{
printf("%d\t %s error", __LINE__, __FILE__); //打印出错的文件和代码行数便于修改
exit(0);
}
if (0 != i && L->length != i)
return L->elem[i];
return 0;
}
/*------------------------------------------------------------
操作目的: 遍历顺序表
初始条件: 线性表L已存在
操作结果: 打印顺序表中的每一个值
函数参数:
SqList L 线性表L
返回值:
无
------------------------------------------------------------*/
void ListTraverse(sqListPtr L)
{
for (int i = 0; i <= L->length -1 ; i++)
printf("%d\t", L->elem[i]);
printf("\n");
}
/*------------------------------------------------------------
操作目的: 清空顺序表
初始条件: 线性表L已存在
操作结果: 将L置为空表
函数参数:
SqList *L 线性表L
返回值:
无
------------------------------------------------------------*/
void ClearList(sqListPtr L)
{
assert(L != NULL); //断言L不为空,如果L为空则所有操作都没有意义
if (L == NULL) //如果L为空
{
printf("%d\t %s error", __LINE__, __FILE__); //打印出错的文件和代码行数便于修改
exit(0);
}
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(sqListPtr L, int i, ElemType e)
{
assert(L != NULL); //断言L不为空,如果L为空则所有操作都没有意义
if (L == NULL) //如果L为空
{
printf("%d\t %s error", __LINE__, __FILE__); //打印出错的文件和代码行数便于修改
exit(0);
}
if ((i < 1) || (i > L->length + 1))
{
printf("pos error\n");
return false;
}
//1.判断线性表是否为满
if (L->length == L->listsize)
{
//2.如果满了就扩容然后插入数据
ElemType* newbase = (ElemType*)realloc(L->elem, (LIST_INIT_SIZE) * 2 * sizeof(ElemType));
if (NULL == newbase)
{
printf("expension fail\n");
return false;
}
L->elem = newbase;
L->listsize *= 2;
for (int j = L->length; j >= i ; j--)
{
L->elem[j] = L->elem[j - 1];
}
L->elem[i - 1] = e;
++L->length;
return true;
}
else
{
//3.如果没有满则直接插入数据
for (int j = L->length; j >= i; j--)
{
L->elem[j] = L->elem[j - 1];
}
L->elem[i - 1] = e;
++L->length;
return true;
}
return false;
}
/*------------------------------------------------------------
操作目的: 删除顺序表的第i个结点
初始条件: 线性表L已存在且非空,1<=i<=ListLength(L)
操作结果: 删除L的第i个数据元素,并用e返回其值,L的长度减1
函数参数:
SqList *L 线性表L
int i 删除位置
ElemType *e 被删除的数据元素值
返回值:
bool 操作是否成功
------------------------------------------------------------*/
bool ListDelete(sqListPtr L, int i)
{
assert(L != NULL); //断言L不为空,如果L为空则所有操作都没有意义
if (L == NULL) //如果L为空
{
printf("%d\t %s error", __LINE__, __FILE__); //打印出错的文件和代码行数便于修改
exit(0);
}
if (i < 1 || i > L->length)
{
printf("pos error\n");
return false;
}
for (int j = i - 1; j < L->length-1; j++)
{
L->elem[j] = L->elem[j + 1];
}
--L->length;
return true;
}
/*------------------------------------------------------------
操作目的: 在顺序表表的头部插入元素
初始条件: 线性表已经存在
操作结果: 在线性表的头部插入一个元素并且把线性表长度+1
函数参数:
SqList *L 线性表L
所需要插入的数据
返回值:
不需要返回值 间接调用ListInsert函数
------------------------------------------------------------*/
void ListInsertHead(sqListPtr L, ElemType e)
{
ListInsert(L,1, e);
}
/*------------------------------------------------------------
操作目的: 在顺序表表的尾部插入元素
初始条件: 线性表已经存在
操作结果: 在线性表的尾部插入一个元素并且把线性表长度+1
函数参数:
SqList *L 线性表L
所需要插入的数据
返回值:
不需要返回值 间接调用ListInsert函数
------------------------------------------------------------*/
void ListInsertTail(sqListPtr L, ElemType e)
{
ListInsert(L, L->length + 1 , e);
}
/*------------------------------------------------------------
操作目的: 在顺序表表的头部删除元素
初始条件: 线性表已经存在
操作结果: 在线性表的头部删除一个元素并且把线性表长度-1
函数参数:
SqList *L 线性表L
返回值:
不需要返回值 间接调用ListDelete函数
------------------------------------------------------------*/
void ListDeleteHead(sqListPtr L)
{
ListDelete(L, 1);
}
/*------------------------------------------------------------
操作目的: 在顺序表表的尾部删除元素
初始条件: 线性表已经存在
操作结果: 在线性表的尾部删除一个元素并且把线性表长度-1
函数参数:
SqList *L 线性表L
返回值:
不需要返回值 间接调用ListDelete函数
------------------------------------------------------------*/
void ListDeleteTail(sqListPtr L)
{
ListDelete(L, L->length);
}
int compare(ElemType x, ElemType y)
{
return(x - y);
}
/****
*
*动态顺序表的定义
*
****/
#pragma once //防止头文件重复包含
#include
#include
#include
#include
#include
typedef int ElemType;
typedef struct List
{
ElemType* elem; //存储空间的基址
int length; //顺序表中已经存储的元素的个数
int listsize; //顺序表的存储空间大小
}SqList,*sqListPtr;
/*------------------------------------------------------------------------------------
//顺序表的基本操作
-------------------------------------------------------------------------------------*/
bool InitList(sqListPtr L); //初始化顺序表
void DestroyList(sqListPtr L); //销毁顺序表
bool ListEmpty(sqListPtr L); //判断顺序表是否为空
int ListLength(sqListPtr L); //得到顺序表的长度
int GetElem(sqListPtr L, int i); //得到顺序表的第i个元素
int PriorElem(sqListPtr L, int i); //得到顺序表指定元素的前驱
int NextElem(sqListPtr L, int i); //得到顺序表指定元素的后继
void ListTraverse(sqListPtr L); //遍历顺序表
void ClearList(sqListPtr L); //清空顺序表
bool ListInsert(sqListPtr L, int i, ElemType e); //在顺序表的指定位置插入结点,插入位置i表示在第i个元素之前插入
void ListInsertHead(sqListPtr L, ElemType e); //在顺序表的起始位置插入元素
void ListInsertTail(sqListPtr L,ElemType e); //在线性表的末尾位置插入元素
bool ListDelete(sqListPtr L, int i);// 删除顺序表的第i个结点
void ListDeleteHead(sqListPtr L ); //删除顺序表的起始元素
void ListDeleteTail(sqListPtr L ); //删除顺序表的末尾元素
int compare(ElemType x, ElemType y);
前面实现求两个线性表的并集只使用到了部分函数功能,我们在这里给出实现动态顺序表的全部功能。