求两个线性表的并集(C语言通过动态顺序表实现)(DataStruct)(g)

这篇博客是关于求两个线性表的并集实现的详细代码,使用C语言实现是使用到的功能都在线性表的动态实现里面,并且有完整的测试和截图

  • main.cpp
  • SqList.cpp
  • SqList.h
  • 小结

main.cpp

#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;
	}

SqList.cpp

#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);
}

SqList.h

/****
*
*动态顺序表的定义
*
****/
#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);

执行结果为:
求两个线性表的并集(C语言通过动态顺序表实现)(DataStruct)(g)_第1张图片

小结

前面实现求两个线性表的并集只使用到了部分函数功能,我们在这里给出实现动态顺序表的全部功能。

你可能感兴趣的:(求两个线性表的并集(C语言通过动态顺序表实现)(DataStruct)(g))