C语言实现求两个线性表的并集

问题说明

求两个线性表的并集:
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;
}

测试结果

测试两个线性表的并集

展开阅读全文
©️2020 CSDN 皮肤主题: 创作都市 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值