C语言线性表

/* 宏定义 */
#define LIST_INIT_SIZE 100				//顺序表存储空间的初始分配量 
#define LISTINCREMENT  10				//顺序表存储空间的分配增量

/* 顺序表类型定义 */
#ifndef LELEMTYPE_SQ
#define LELEMTYPE_SQ
typedef int LElemType_Sq;
#endif

typedef struct
{
	LElemType_Sq *elem;					//存储空间基址(指向第一个结点的指针) 
	int length;							//当前顺序表长度 
	int listsize;						//当前分配的存储容量 
}SqList;								//顺序表0号单元正常使用 

线性表基本操作

Status InitList_Sq(SqList *L)
{
	(*L).elem = (LElemType_Sq*)malloc(LIST_INIT_SIZE*sizeof(LElemType_Sq));
	if(!(*L).elem)
		exit(OVERFLOW); 				//分配内存失败

	(*L).length = 0;					//初始化顺序表长度为0
	(*L).listsize = LIST_INIT_SIZE;		//顺序表初始内存分配量

	return OK;							//初始化成功	 
} 

void ClearList_Sq(SqList *L)
{
	(*L).length = 0;
}

void DestroyList_Sq(SqList *L)
{
	free((*L).elem);

	(*L).elem = NULL;					//释放内存后置空指针 
	(*L).length = 0;
	(*L).listsize = 0;
}

Status ListEmpty_Sq(SqList L)
{
	return 	L.length==0 ? TRUE : FALSE;
}

int ListLength_Sq(SqList L)
{
	return L.length;	
}

Status GetElem_Sq(SqList L, int i, LElemType_Sq *e)
{ 
	if(i<1 || i>L.length)
		return ERROR;					//i值不合法
	else
		*e = L.elem[i-1];

	return OK;
}

/*════╗
║算法2.6 ║ 
╚════*/
int LocateElem_Sq(SqList L, LElemType_Sq e, Status(Compare)(LElemType_Sq, LElemType_Sq))
{
	int i = 1;							//i的初值为第一个元素的位序
	
	while(i<=L.length && !Compare(e, L.elem[i-1]))
		++i;

	if(i<=L.length)
		return i;
	else
		return 0; 
}

Status PriorElem_Sq(SqList L, LElemType_Sq cur_e, LElemType_Sq *pre_e)
{
	int i = 1;
	
	if(L.elem[0]!=cur_e)				//第一个结点无前驱 
	{
		while(i<L.length && L.elem[i]!=cur_e)
			++i;
		
		if(i<L.length)
		{
			*pre_e = L.elem[i-1];
			return OK;
		}	
	}
			
	return ERROR;
}

Status NextElem_Sq(SqList L, LElemType_Sq cur_e, LElemType_Sq *next_e)
{
	int i = 0;
	
	while(i<L.length && L.elem[i]!=cur_e)
		++i;

	if(i<L.length-1)					//最后一个结点无后继 
	{
		*next_e = L.elem[i+1];	
		return OK;
	}

	return ERROR;
}

/*════╗
║算法2.4 ║ 
╚════*/
Status ListInsert_Sq(SqList *L, int i, LElemType_Sq e)
{
	LElemType_Sq *newbase; 
	LElemType_Sq *p, *q;

	if(i<1 || i>(*L).length+1)
		return ERROR;					//i值不合法

	if((*L).length >= (*L).listsize)	//若存储空间已满,需开辟新空间 
	{
		newbase = (LElemType_Sq*)realloc((*L).elem, ((*L).listsize+LISTINCREMENT)*sizeof(LElemType_Sq));
		if(!newbase)
			exit(OVERFLOW);

		(*L).elem = newbase;
		(*L).listsize += LISTINCREMENT;
	}
	
	q = &(*L).elem[i-1];				//q为插入位置 
	
	for(p=&(*L).elem[(*L).length-1]; p>=q; --p)
		*(p+1) = *p;					//插入位置及之后的元素右移 
	
	*q = e;								//插入e 
	(*L).length++;						//表长增1

	return OK; 
}

/*════╗
║算法2.5 ║ 
╚════*/
Status ListDelete_Sq(SqList *L, int i, LElemType_Sq *e)
{
	LElemType_Sq *p, *q;
		
	if(i<1 || i>(*L).length)
		return ERROR;					//i值不合法
	
	p = &(*L).elem[i-1];				//p为被删除元素的位置 
	*e = *p;
	q = (*L).elem+(*L).length-1; 		//表尾元素位置 
	
	for(++p; p<=q; ++p)
		*(p-1) = *p;					//被删元素之后的元素左移 

	(*L).length--;						//表长减1

	return OK;
}

Status ListTraverse_Sq(SqList L, void(Visit)(LElemType_Sq))
{
	int i;

	for(i=0; i<L.length; i++)
		Visit(L.elem[i]);
	
	return OK;
}
/* 测试调用的函数原型 */
Status CmpGreater(LElemType_Sq e, LElemType_Sq data);
	//若data>e,返回TRUE,否则返回FALSE
	
void PrintElem(LElemType_Sq e);
	//测试函数,打印整型 

int main(int argc, char **argv)
{
	SqList L;
	int i;
	LElemType_Sq e;

	printf("▼1\n▲函数 InitList_Sq 测试...\n");		//1.函数InitList_Sq测试
	{
		printf("初始化顺序表 L ...\n");					 
		InitList_Sq(&L);
		printf("\n");	
	}
	PressEnter;
	
	printf("▼4\n▲函数 ListEmpty_Sq 测试...\n");		//4.函数ListEmpty_Sq测试
	{
		ListEmpty_Sq(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
		printf("\n");	
	}
	PressEnter;
		
	printf("▼10\n▲函数 ListInsert_Sq 测试...\n");		//10.函数ListInsert_Sq测试
	{
		for(i=1; i<=6; i++)									
		{
			printf("作为示范,在 L 第 %d 个位置插入 \"%d\"...\n", i, 2*i);
			ListInsert_Sq(&L, i, 2*i);
		}
		printf("\n");	
	}
	PressEnter;
			
	printf("▼12\n▲函数 ListTraverse_Sq 测试...\n");	//12.函数ListTraverse_Sq测试
	{
		printf(" L 中的元素为:L = ");						 
		ListTraverse_Sq(L, PrintElem);
		printf("\n\n");	
	}
	PressEnter;
		
	printf("▼5\n▲函数 ListLength_Sq 测试...\n");		//5.函数ListLength_Sq测试
	{
		i = ListLength_Sq(L);
		printf(" L 的长度为 %d \n", i);
		printf("\n");	
	}
	PressEnter;
			
	printf("▼11\n▲函数 ListDelete_Sq 测试...\n");		//11.函数ListDelete_Sq测试
	{
		ListDelete_Sq(&L, 6, &e);
		printf("删除 L 中第 6 个元素 \"%d\" ...\n", e);
		printf(" L 中的元素为:L = ");						 
		ListTraverse_Sq(L, PrintElem);
		printf("\n\n");
	}
	PressEnter;
		
	printf("▼6\n▲函数 GetElem_Sq 测试...\n");			//6.函数GetElem_Sq测试
	{
		GetElem_Sq(L, 4, &e);
		printf(" L 中第 4 个位置的元素为 \"%d\" \n", e);
		printf("\n");
	}
	PressEnter;
		
		
	printf("▼7\n▲函数 LocateElem_Sq 测试...\n");	  	//7.函数LocateElem_Sq测试
	{
		i = LocateElem_Sq(L, 7, CmpGreater);
		printf(" L 中第一个元素值大于 \"7\" 的元素的位置为 %d \n", i); 
		printf("\n");
	}
	PressEnter;
		
	printf("▼8\n▲函数 PriorElem_Sq 测试...\n");		//8.函数PriorElem_Sq测试
	{
		PriorElem_Sq(L, 6, &e);
		printf("元素 \"6\" 的前驱为 \"%d\" \n", e);
		printf("\n");
	}
	PressEnter;
		
	printf("▼9\n▲函数 NextElem_Sq 测试...\n");		//9.函数NextElem_Sq测试
	{
		NextElem_Sq(L, 6, &e);
		printf("元素 \"6\" 的后继为 \"%d\" \n", e);
		printf("\n");
	}
	PressEnter;
		
	printf("▼2\n▲函数 ClearList_Sq 测试...\n");		//2.函数ClearList_Sq测试
	{
		printf("清空 L 前:");
		ListEmpty_Sq(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");		
		ClearList_Sq(&L);
		printf("清空 L 后:");
		ListEmpty_Sq(L) ? printf(" L 为空!!\n") : printf(" L 不为空!\n");
		printf("\n");
	}
	PressEnter;
		
	printf("▼3\n▲函数 DestroyList_Sq 测试...\n");		//3.函数DestroyList_Sq测试
	{
		printf("销毁 L 前:");
		L.elem ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
		DestroyList_Sq(&L);
		printf("销毁 L 后:");
		L.elem ? printf(" L 存在!\n") : printf(" L 不存在!!\n");
		printf("\n");
	}
	PressEnter;
		
	return 0;
}

Status CmpGreater(LElemType_Sq e, LElemType_Sq data)
{
	return data>e ? TRUE : FALSE;
}

void PrintElem(LElemType_Sq e)
{
	printf("%d ", e);
}

线性表并集∪

/*════╗
║ 算法2.1║ 
╚════*/
void Union(SqList *La, SqList Lb)
{
	int La_len, Lb_len;
	int i;
	LElemType_Sq e;
	
	La_len = ListLength_Sq(*La);			//求顺序表长度 
	Lb_len = ListLength_Sq(Lb);
	
	for(i=1; i<=Lb_len; i++)
	{
		GetElem_Sq(Lb, i, &e);				//取Lb中第i个元素赋给e 
		if(!LocateElem_Sq(*La, e, equal)) 	//若e不在La中则插入
			ListInsert_Sq(La, ++La_len, e);	
	}
}

Status equal(LElemType_Sq e1, LElemType_Sq e2)
{
   return e1==e2 ? TRUE : FALSE;
}
void PrintElem(LElemType_Sq e);		//测试函数,打印整型 
	
int main(int argc, char **argv)
{
	SqList La, Lb;
	LElemType_Sq a[5] = {5, 2, 1, 3, 9};
	LElemType_Sq b[7] = {7, 2, 6, 9, 11, 3, 10};
	int i;
	
	InitList_Sq(&La);					//初始化La 
	for(i=1; i<=5; i++)
		ListInsert_Sq(&La, i, a[i-1]);	
	InitList_Sq(&Lb);					//初始化Lb 
	for(i=1; i<=7; i++)
		ListInsert_Sq(&Lb, i, b[i-1]);

	printf("La = ");					//输出La 
	ListTraverse_Sq(La, PrintElem); 
	printf("\n");
	printf("Lb = ");					//输出Lb 
	ListTraverse_Sq(Lb, PrintElem); 
	printf("\n\n");
	
	printf("La = La∪Lb = ");			//输出新表La的内容
	Union(&La, Lb);
	ListTraverse_Sq(La, PrintElem);
	printf("\n\n");
	
	return 0;
}

void PrintElem(LElemType_Sq e)
{
	printf("%d ", e);
}

线性表合并

/*━━━━━━━━━━━━━━━━━━━━━┓
┃算法2.2:求C=A+B,A,B,C均为非递减序列 ┃
┗━━━━━━━━━━━━━━━━━━━━━*/
void MergeSqList_1(SqList La, SqList Lb, SqList *Lc)	//调用顺序表函数进行合并 
{
	int La_len, Lb_len; 
	int i, j, k;
	LElemType_Sq ai, bj;
	
	i = j = 1;
	k = 0;
	
	InitList_Sq(Lc);					//初始化Lc	
	La_len = ListLength_Sq(La);			//获取La、Lb长度 
	Lb_len = ListLength_Sq(Lb);	 

	while(i<=La_len && j<=Lb_len)		//La及Lb均未扫描完 
	{
		GetElem_Sq(La, i, &ai);
     	GetElem_Sq(Lb, j, &bj);
     	
     	if(ai<=bj)
     	{
     		ListInsert_Sq(Lc, ++k, ai);
     		i++;
     	}
     	else
     	{
			ListInsert_Sq(Lc, ++k, bj);
			j++;
		}
	} 
	
	while(i<=La_len)					//表La还未扫描完 
	{
		GetElem_Sq(La, i++, &ai);
		ListInsert_Sq(Lc, ++k, ai);
	}
   
	while(j<=Lb_len)					//表Lb还未扫描完
	{
		GetElem_Sq(Lb, j++, &bj);
		ListInsert_Sq(Lc, ++k, bj);
	}
}

/*━━━━━━━━━━━━━━━━━━━━━┓
┃算法2.7:求C=A+B,A,B,C均为非递减序列 ┃
┗━━━━━━━━━━━━━━━━━━━━━*/
void MergeSqList_2(SqList La, SqList Lb, SqList *Lc)
{
	LElemType_Sq *pa, *pb, *pc;
	LElemType_Sq *pa_last, *pb_last;
		
	pa = La.elem;						//指向La第一个元素 
	pb = Lb.elem;						//指向Lb第一个元素
	
										//不用InitList_Sq创建Lc 
	(*Lc).listsize = (*Lc).length = La.length + Lb.length;
	pc = (*Lc).elem = (LElemType_Sq *)malloc((*Lc).listsize*sizeof(LElemType_Sq));
	if(!pc) 
		exit(OVERFLOW);
	
	pa_last = La.elem + La.length - 1;	//指向La最后一个元素
	pb_last = Lb.elem + Lb.length - 1;	//指向Lb最后一个元素
	
	while(pa<=pa_last && pb<=pb_last) 	//La和Lb均未扫描完 
	{
		if(*pa <= *pb)
			*pc++ = *pa++;
		else
			*pc++ = *pb++;
	}
	
	while(pa <= pa_last)				//表La未扫描完 
		*pc++ = *pa++;					//插入La的剩余元素

	while(pb <= pb_last)				//表Lb未扫描完
		*pc++ = *pb++;					//插入Lb的剩余元素
}
void PrintElem(LElemType_Sq e);			//测试函数,打印整型 
	
int main(int argc, char **argv)
{
	SqList La, Lb, Lc1, Lc2;
	LElemType_Sq a[4] = {3, 5, 8, 11};
	LElemType_Sq b[7] = {2, 6, 8, 9, 11, 15, 20};
	int i;
	
	InitList_Sq(&La);					//初始化La 
	for(i=1; i<=4; i++)
		ListInsert_Sq(&La, i, a[i-1]);	
	InitList_Sq(&Lb);					//初始化Lb 
	for(i=1; i<=7; i++)
		ListInsert_Sq(&Lb, i, b[i-1]);

	printf("La = ");					//输出La 
	ListTraverse_Sq(La, PrintElem); 
	printf("\n");
	printf("Lb = ");					//输出Lb 
	ListTraverse_Sq(Lb, PrintElem); 
	printf("\n\n");
	
	MergeSqList_1(La, Lb, &Lc1);		//合并A与B,算法2.6 
	printf("合并La和Lb为Lc1 = "); 		//输出Lc1 
	ListTraverse_Sq(Lc1, PrintElem);
	printf("\n\n");

	MergeSqList_2(La, Lb, &Lc2);		//合并A与B,算法2.7  
	printf("合并La和Lb为Lc2 = "); 		//输出Lc2 
	ListTraverse_Sq(Lc2, PrintElem);
	printf("\n\n");
	
	return 0;
}

void PrintElem(LElemType_Sq e)
{
	printf("%d ", e);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

取个名字真难啊啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值