线性表的顺序存储结构实现(严蔚敏《数据结构》p17)

/*
* 功能:顺序表实现(严蔚敏《数据结构》p19)
* 作者:风清扬
* 日期:2014-12-31
* 版本:V1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define TRUE	1
#define FALSE	0
#define OK		1
#define ERROR	0

#define INFEASIBLE	-1
#define OVERFLOW	-2

#define LIST_INIT_SIZE 10
#define LIST_INCREMENT 2

typedef int Status;
typedef int ElemType;

Status IsEqual(ElemType e1, ElemType e2);
void ElemPrint(ElemType e);

//=============================================================================
/*-------------------------------顺序表类型定义------------------------------*/
typedef struct
{
	ElemType *base;
	int length;
	int listSize;
} SqList;

void InitList_Sq(SqList &L);
void DestroyList_Sq(SqList &L);
void ClearList_Sq(SqList &L);
Status ListEmpty_Sq(SqList L);
int ListLength_Sq(SqList L);
Status GetElem_Sq(SqList L, int pos, ElemType &e);
int LocateElem_Sq(SqList L, ElemType e, Status (*compare)(ElemType,ElemType));
Status PriorElem_Sq(SqList L, ElemType e, ElemType &pri_e);
Status NextElem_Sq(SqList L, ElemType e, ElemType &next_e);
Status ListInsert_Sq(SqList &L, int pos, ElemType e);
Status ListDelete_Sq(SqList &L, int pos, ElemType &e);
void ListTraverse_Sq(SqList L, void (*visit)(ElemType));
//=============================================================================

//=================================================================================================
int main(void)
{
	SqList L;
	ElemType e, pri_e, next_e;
	Status i; //函数结果状态量
	int j, k;

	InitList_Sq(L);
	printf("初始化L后:L.base=%u L.length=%d L.listSize=%d\n", L.base, L.length, L.listSize);
	for(j=1; j<=LIST_INIT_SIZE; ++j)
		ListInsert_Sq(L,1,j);
	printf("从表头插满元素后,表中元素为: ");
	ListTraverse_Sq(L, ElemPrint);
	printf("L.base=%u L.length=%d L.listSize=%d\n", L.base, L.length, L.listSize);
	i = ListEmpty_Sq(L);
	printf("===================================================================\n");
	printf("L是否空: i=%d(1:是 0:否)\n", i);
	ClearList_Sq(L);
	printf("清空L后: L.base=%u L.length=%d L.listSize=%d\n", L.base, L.length, L.listSize);
	i = ListEmpty_Sq(L);
	printf("L是否空: i=%d(1:是 0:否)\n", i);
	printf("===================================================================\n");
	for(j=1; j<=LIST_INIT_SIZE; j++)
		ListInsert_Sq(L,j,j);
	printf("从表尾插满元素后,表中元素为:");
	ListTraverse_Sq(L, ElemPrint);
	printf("L.base=%u L.length=%d L.listSize=%d\n", L.base, L.length, L.listSize);
	printf("===================================================================\n");
	ListInsert_Sq(L,1,0);
	printf("在L的表头插入0后,表中元素为: ");
	ListTraverse_Sq(L, ElemPrint);
	printf("L.base=%u L.length=%d L.listsize=%d\n", L.base, L.length, L.listSize);
	printf("===================================================================\n");
	GetElem_Sq(L, 5, e);
	printf("第5个元素的值为: %d\n",e);
	printf("===================================================================\n");
	for(j=10; j<=11; ++j)
	{
		k = LocateElem_Sq(L, j, IsEqual);
		if(k) // k不为0,表明有符合条件的元素,且其位序为k
			printf("第%d个元素的值为%d\n", k, j);
		else
			printf("没有值为%d的元素\n", j);
	}
	printf("===================================================================\n");
	for(j=1; j<=2; ++j)
	{
		GetElem_Sq(L, j, e); //把第j个数据赋给e
		i = PriorElem_Sq(L, e, pri_e); //求e的前驱
		if(INFEASIBLE == i)
			printf("元素%d无前驱\n",e);
		else
			printf("元素%d的前驱为%d\n", e, pri_e);
	}
	printf("===================================================================\n");
	for(j=L.length-1; j<=L.length; ++j) //最后两个数据
	{
		GetElem_Sq(L,j,e); //把第j个数据赋给e
		i=NextElem_Sq(L,e,next_e); // 求e的后继
		if(INFEASIBLE == i)
			printf("元素%d无后继\n", e);
		else
			printf("元素%d的后继为%d\n", e, next_e);
	}
	printf("===================================================================\n");
	k = ListLength_Sq(L); 
	for(j=k+1; j>=k; --j)
	{
		i = ListDelete_Sq(L, j, e); //删除第j个数据
		if(ERROR == i)
			printf("删除第%d个元素失败!\n", j);
		else
			printf("删除第%d个元素成功,其值为%d!\n", j, e);
	}
	printf("依次输出L的元素:");
	ListTraverse_Sq(L,ElemPrint); //依次对元素调用ElemPrint,输出元素的值
	printf("===================================================================\n");
	DestroyList_Sq(L);
	printf("销毁L后:L.elem=%u L.length=%d L.listsize=%d\n",L.base,L.length,L.listSize);
	printf("===================================================================\n");

	return 0;
}
//=================================================================================================

//=========================================================================================
/*--------------------------------顺序表基本功能的实现-----------------------------------*/
void InitList_Sq(SqList &L)
{//构造一个空的线性表L
	L.base = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
	if (!L.base)
	{
		printf("内存不足,初始化失败,程序终止!\n");
		exit(OVERFLOW);
	}
	L.length = 0;
	L.listSize = LIST_INIT_SIZE;	
}

void DestroyList_Sq(SqList &L)
{//销毁线性表L
	free(L.base);
	L.base = NULL;
	L.length = 0;
	L.listSize = 0;
}

void ClearList_Sq(SqList &L)
{//将L重置为空表
	L.length = 0;
}

Status ListEmpty_Sq(SqList L)
{//若L为空表,则返回TRUE,否则返回FALSE。
	if (0 == L.length)
		return TRUE;
	else
		return FALSE;
}

int ListLength_Sq(SqList L)
{//返回线性表L中数据元素的个数
	return L.length;
}

Status GetElem_Sq(SqList L, int pos, ElemType &e)
{//用e返回L中第pos个数据元素的值
	if (pos<1 || pos>L.length)
		return ERROR;
	e = L.base[pos-1];
	return OK;
}

int LocateElem_Sq(SqList L, ElemType e, Status (*compare)(ElemType,ElemType))
{//返回L中第1个与e满足关系compare()的数据元素的位序,如果不存在,则返回0
	int i = 1;
	ElemType * p = L.base;
	
	while (i<=L.length && !compare(*p,e))
	{
		++p;
		++i;
	}
	if (i > L.length)
		return 0;
	else
		return i;
}

Status PriorElem_Sq(SqList L, ElemType e, ElemType &pri_e)
{//若e是L的数据元素,且不是第一个,则用pri_e返回它的前驱;
 //否则操作失败,pri_e无定义
	int i = 2;
	ElemType *p = L.base+1;

	while (i<=L.length && *p!=e)
	{
		++p;
		++i;
	}
	if (i > L.length)
		return INFEASIBLE;
	else
	{
		pri_e = L.base[i-1];
		return OK;
	}
}

Status NextElem_Sq(SqList L, ElemType e, ElemType &next_e)
{//若e是L的数据元素,且不是最后一个,则用next_e返回它的后继;
 //否则操作失败,next_e无定义
	int i = 1;
	ElemType *p = L.base;

	while (i<L.length && *p!=e)
	{
		++p;
		++i;
	}
	if (i == L.length)
		return INFEASIBLE;
	else
	{
		
		next_e = L.base[i+1];
		return OK;
	}
}

Status ListInsert_Sq(SqList &L, int pos, ElemType e)
{
	ElemType *p, *q = L.base+pos-1;

	if (pos<1 || pos>L.length+1 )
		return ERROR;
	if (L.length == L.listSize)
	{//线性表中容量满,增加容量。
		L.base = (ElemType *)realloc(L.base,(L.listSize+LIST_INCREMENT)*sizeof(ElemType));
		if (!L.base)
		{
			printf("顺序表容量增加失败,程序终止!\n");
			exit(OVERFLOW);
		}
		L.listSize += LIST_INCREMENT;
	}
	for (p=L.base+L.length-1; p>=q; --p)
		*(p+1) = *p;
	*q = e;
	++L.length;
	return OK;
}

Status ListDelete_Sq(SqList &L,int pos, ElemType &e)
{
	ElemType *p, *q = L.base+pos-1;

	if (pos<1 || pos>L.length)
		return ERROR;
	for (p=q+1; p<=L.base+L.length-1; ++p)
		*(p-1) = *p;
	e = *q;
	--L.length;
	return OK;
}

void ListTraverse_Sq(SqList L, void (*visit)(ElemType))
{
	int i;

	for (i=0; i<L.length; ++i)
		visit(L.base[i]);
	printf("\n");
}


Status IsEqual(ElemType e1, ElemType e2)
{//比较函数,这个可以根据具体情况修改想要比较的关系
	if(e1 == e2)
		return TRUE;
	else
		return FALSE;
}

void ElemPrint(ElemType e)
{//遍历函数,这个可以根据具体情况修改想要做的遍历操作
	printf("%d ", e);
}


测试结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值