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

測試結果

測試兩個線性表的並集

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章