数据结构——线性表的顺序表示和实现(c语言)

PS:数据结构(C语言版)——清华大学出版社, 2.1节代码实现
#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1  
#define OVERFLOW -2
#define LIST_INIT_SIZE 100   //顺序表初始分配空间
#define LISTINCREMENT 10   //顺序表存储空间分配增量

//Status是函数的类型,其值是函数结果状态码
typedef int Status;
typedef int ElemType;   //顺序表存储元素类型, 考虑到可移植性, 若改变存储类型, 只需修改这一处,比较方便
typedef struct 
{
	ElemType *elem;   //存储空间地址
	int length;   //当前长度
	int listsize;   //当前分配的存储容量(以sizeof(ElemType)为单位)
}SqList;

void Init_Sq(SqList *L);
Status Insert_Sq(SqList *L, int i, ElemType e);
Status Destroy_Sq(SqList *L);
Status Delete_List(SqList *L, int i);
void Travse_Sq(SqList *L);
ElemType Next_Elem(SqList *L, int cur_elem);
ElemType Prior_Elem(SqList *L, int cur_elem);
ElemType GetElem(SqList *L, int i);
int LocateElem_Sq(SqList *L, ElemType e);
Status compare(ElemType e1, ElemType e2);
int ListLength(SqList *L);
void union_Sq(SqList *La, SqList *Lb);
void Merge_Sq(SqList *La, SqList *Lb, SqList *Lc);

void main()
{	

	/*SqList L;
	int i;
	Init_Sq(&L);
	if(	Insert_Sq(&L, 1, 4))
	{
		printf("The element is %d\n", GetElem(&L, 1));
	}
	if(	Insert_Sq(&L, 2, 5))
	{
		printf("The element is %d\n", GetElem(&L, 2));
	}
	if(	Insert_Sq(&L, 3, 6))
	{
		printf("The element is %d\n", GetElem(&L, 3));
	}
	if(	Insert_Sq(&L, 4, 8))
	{
		printf("The element is %d\n", GetElem(&L, 4));
	}
	if(	Insert_Sq(&L, 5, 18))
	{
		printf("The element is %d\n", GetElem(&L, 5));
	}
	Travse_Sq(&L);
	printf("Current number:  ");
	scanf("%d", &i);
	printf("The prior of No.%d is %d\n", i, Prior_Elem(&L, i));

	
	if(Delete_List(&L,1))
	{
		printf("After delete:\n");
		Travse_Sq(&L);
	}
	*/

	SqList La;
	SqList Lb;
	SqList Lc;

	Init_Sq(&La);
	Init_Sq(&Lb);

	if(	Insert_Sq(&La, 1, 4))
	{
		printf("The element in La is %d\n", GetElem(&La, 1));
	}
	if(	Insert_Sq(&La, 2, 5))
	{
		printf("The element in La is %d\n", GetElem(&La, 2));
	}
	if(	Insert_Sq(&La, 3, 6))
	{
		printf("The element in La is %d\n", GetElem(&La, 3));
	}
	if(	Insert_Sq(&La, 4, 8))
	{
		printf("The element in La is %d\n", GetElem(&La, 4));
	}
	if(	Insert_Sq(&La, 5, 18))
	{
		printf("The element in La is %d\n", GetElem(&La, 5));
	}

	printf("\n");
	if(	Insert_Sq(&Lb, 1, 4))
	{
		printf("The element in Lb is %d\n", GetElem(&Lb, 1));
	}
	if(	Insert_Sq(&Lb, 2, 15))
	{
		printf("The element in Lb is %d\n", GetElem(&Lb, 2));
	}
	printf("\n");

	//union_Sq(&La, &Lb);   

//	printf("After unite La and Lb:\n");
//	Travse_Sq(&La);
	Merge_Sq(&La, &Lb, &Lc);
	printf("After merge La and Lb:\n");
	Travse_Sq(&Lc);
	Destroy_Sq(&La);
	Destroy_Sq(&Lb);
	Destroy_Sq(&Lc);
}

void Init_Sq(SqList *L)
{
	L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
	if(L->elem == NULL)
	{
		printf("Memory allocation is error!");
		exit(1);   //0表示正常退出,非零表示异常退出
	}
	L->length = 0;
	L->listsize = LIST_INIT_SIZE;
}

//在第i个位置插入元素e
Status Insert_Sq(SqList *L, int i, ElemType e)
{
	ElemType *newbase;   //指向新增顺序表后的起始位置
	ElemType *p;
	ElemType *q;

	if(i < 1 || i > L->length +  1)
	{
		printf("The location that inserted is illegal!\n");
		return TRUE;
	}

	if(!(L->length < L->listsize))   //如果顺序表满了就扩充
		newbase = (ElemType *)realloc(&L->elem, (L->length + LISTINCREMENT) * sizeof(ElemType));

	p = &L->elem[i-1];

	for(q = &L->elem[L->length - 1]; p <= q; q--)
	{
		*(q + 1) = *q;
	}

	*p = e;
	L->length ++;
	return TRUE;
}

//销毁顺序表
Status Destroy_Sq(SqList *L)
{
	if(L->length < 1)
		return FALSE;
	free(L->elem);
	L->elem = NULL;
	return TRUE;
}

//删除顺序表中指定元素
Status Delete_List(SqList *L, int i)
{
	ElemType *p;
	int j;

	if(i < 1 && i > L->length)
	{
		printf("The site that store element is not exist!\n");
		return FALSE;
	}

	p = &L->elem[i - 1];   //初始使p指向将要删除的位置

	for(j = i - 1; j < L->length - 1; j++)
	{
		*p = *(p+1);
		p++;
	}
	L->length --;
	return TRUE;
}

//遍历顺序表
void Travse_Sq(SqList *L)
{
	int i;
	if(L->length == 0)
	{
		printf("The sequence list is empty!\n");
	}
	else
		for(i = 0; i < L->length; i++)
			printf("The No.%d is %d.\n", i, L->elem[i]);
}

//返回第i个数据
ElemType GetElem(SqList *L, int i)
{
	if(i < 1 || i > L->length)
		return ERROR;
	return L->elem[i - 1];
}

//返回第cur_elem个元素的直接前驱
ElemType Prior_Elem(SqList *L, int cur_elem)
{
	if(cur_elem == 1)
		return ERROR;
	else
		return L->elem[cur_elem - 2];
}

//返回第cur_elem个元素的直接后继
ElemType Next_Elem(SqList *L, int cur_elem)
{
	if(cur_elem == (L->length - 1))
		return FALSE;
	else
		return L->elem[cur_elem];
}

//记录线性表的长度
int ListLength(SqList *L)
{
	if(L->length == 0)
	{
		printf("The sequence list is empty!\n");
		return 0;
	}
	else 
		return L->length;

}

//线性表A和B作并集操作
void union_Sq(SqList *La, SqList *Lb)
{
	//将所有在线性表Lb中但不在La中的数据元素插入到La中
	int La_len, Lb_len;
	int i;
	int Lb_cur_elem;   //记录Lb中取出的元素

	La_len = ListLength(La);
	Lb_len = ListLength(Lb);

	//注意,取的是第i个元素,是从人们熟悉的1开始计数
	//GetElem()函数中会做减1处理(计算机的计数方式)
	for(i = 1; i <= Lb_len; i++)
	{
		Lb_cur_elem = GetElem(Lb, i);
		if(!LocateElem_Sq(La, Lb_cur_elem))
			Insert_Sq(La, ++La_len, Lb_cur_elem);
	}
}

Status compare(ElemType e1, ElemType e2)
{
	if(e1 == e2)
		return TRUE;
	else 
		return FALSE;
}

//在顺序线性表L中查找第一个值与e满足compare()的元素的位序
//若找到,则返回其在L中的位序,否则返回0
int LocateElem_Sq(SqList *L, ElemType e)
{
	int i;
	ElemType *p;
	i = 1;   //i的初值为第一个元素的位序
	p = L->elem;   //p的初值为第1个元素的存储位置
	while(i <= L->length && (e != *p++))
		i++;
	if(i <= L->length)
		return i;
	else 
		return 0;
}

//已知顺序线性表La,和Lb的元素按值非减排列
//归并La和Lb得到新的顺序线性表Lc,Lc的元素也是按值非减排列
void Merge_Sq(SqList *La, SqList *Lb, SqList *Lc)
{
	ElemType *pa;
	ElemType *pb;
	ElemType *pc;
	ElemType *pa_last;
	ElemType *pb_last;

	//给Lc的elem元素分配空间
	Lc->elem = (ElemType *)malloc((La->length + Lb->length) * sizeof(ElemType));
	if(!Lc->elem)
	{
		printf("Error!\n");
		exit(1);
	}

	pa = La->elem;   //pa指向La的第一个元素
	pb = Lb->elem;	 //pb指向Lb的第一个元素		
	pc = Lc->elem;   //pc指向Lc的首地址
	Lc->length = La->length + Lb->length;
	
	pa_last = &La->elem[La->length - 1];   //指向La的最后一个元素(La中的最大的元素)
	pb_last = &Lb->elem[Lb->length - 1];   //指向Lb的最后一个元素(Lb中的最大的元素)

	while(pa <= pa_last && pb <= pb_last)   //实现归并
	{
		if(*pa <= *pb)
		{
			*pc++ = *pa++;
		}
		else
			*pc++ = *pb++;
	}
	while(pa <= pa_last)
		*pc++ = *pa++;
	while(pb <= pb_last)
		*pc++ = *pb++;
}	 

  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值