线性表的顺序表示和实现

上传源码,学习交流,有什么需要改进的地方还希望各位给予指点。

参考书目:《数据结构(C语言版)》,严蔚敏

common.h

#ifndef	_COMMON_H_
#define	_COMMON_H_

#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE  -1
#define OVERFLOW    -2

typedef int Status;  


Status Equal(int a, int b);

#endif


common.c

#include "Common.h"

Status Equal(int a, int b)
{
	if(a==b)	return TRUE;
	else	return FALSE;
}


SqList.h

#ifndef	_SQLIST_H_
#define	_SQLIST_H_

#include <stdlib.h>
#include "Common.h"

#define ElemType int

#define LIST_INIT_SIZE	10	//线性表存储空间的初始分配量
#define LISTINCREMENT	10	//线性表存储空间的分配增量

typedef struct	SqList_
{
	ElemType  *elem;	 //存储空间基址
	int		  length;	 //当前长度
	int		  listsize;	 //当前分配的存储容量(以sizeof(ElemType)为单位)
} SqList;

//基本操作

Status InitList_Sq(SqList *L);
	//操作结果:构造一个空的线性表L

Status ListInsert_Sq(SqList	*L,int i,ElemType e);
	//初始条件:线性表L已存在,1 <= i <= ListLength(&L) + 1
    //操作结果:在线性表L的第i个位置之前插入新元素e,L长度加1

Status ListScanf_Sq(SqList *L);
	//初始条件:线性表L已存在
    //操作结果:向L中输入数据

Status ListDisp_Sq0(SqList *L);	//实际应用时不使用这个函数
	//初始条件:线性表L已存在
    //操作结果:显示L中的元素,遇到0时终止,并且不显示0。(显然不可靠)

Status ListDisp_Sq(SqList *L);
	//初始条件:线性表L已存在
    //操作结果:显示当前L中所有的元素

Status ListDelete_Sq(SqList *L,int i,ElemType *e);
	//初始条件:线性表L已存在且非空,1 <= i <= ListLength(&L)
	//删除L的第i个数据元素,并用e返回其值,L的长度减1

int LocateElem_Sq(SqList *L,ElemType e,Status (*compare)(ElemType ,ElemType ));


#endif


SqList.c

#include <stdio.h>
#include <stdlib.h>
#include "SqList.h"

/*
输入参数:*L     待初始化的线性表头结点
返回参数:OVERFLOW		存储空间不够用
		   OK			初始化成功
函数功能:对顺序线性表头结点进行初始化
*/
Status InitList_Sq(SqList *L)
{
	L->elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
	if(!L->elem)
		exit(OVERFLOW);		//存储分配失败
	L->length = 0;				//空表长度为0
	L->listsize = LIST_INIT_SIZE;	//初始存储容量

	return OK;
}

/*
输入参数:*L	待处理的线性表头结点
返回参数:线性表的当前长度
函数功能:返回线性表的当前长度
*/
int ListLength_Sq(SqList *L)
{
	return(L->length);
}

/*
输入参数:*L	待输入线性表的头结点
返回参数:ERROR	失败
		   OK		成功
函数功能:向指定的线性表输入数据,每输入完一个数据按一下回车(或者空格键),约定当输入0时自动终止输入,并将0存入线性表。
	说明:若想向线性表中输入0,则可以通过函数ListInsert_Sq()来实现。
*/
Status ListScanf_Sq(SqList *L)
{
	SqList	*p;
	p=L;

	if(p == NULL)
	{
		return ERROR;	//该链表不存在
	}
	scanf("%d",(p->elem + p->length));
	while(p->elem[p->length] != 0)
	{
		p->length++;
		if(p->length >= L->listsize)
		{
			printf("The linear list is full.");
			break;
		}
		scanf("%d",(p->elem + p->length));
	}
	return OK;
}

/*
输入参数:*L	待显示线性表的头结点
返回参数:ERROR	失败
		   OK		成功
函数功能:显示线性表,遇到0时终止,并且不显示0
*/
Status ListDisp_Sq0(SqList *L)
{
	unsigned int i=0;
	SqList *p=L;

	if(p == NULL)
	{
		return ERROR;	//该链表不存在
	}
	printf("\n\n\n************** output start **************\n");
	while(p->elem[i] != 0)	//这个判断只能显示非0的元素,且一旦遇到0就会停止显示,这只针对我定义的ListScanf()函数。而且当线性表中的所有数据都不为0时,该判断还会显示线性表之外的数据。然而我们可以按照线性表长度来显示线性表中所有的元素。
	{
		printf("%d	",p->elem[i++]);
	}
	printf("\n************** output end **************\n");
	return OK;
}

/*
输入参数:*L	待显示线性表的头结点
返回参数:ERROR	失败
		   OK		成功
函数功能:按顺序线性表的长度显示线性表,即显示当前线性表中所有的元素
*/
Status ListDisp_Sq(SqList *L)
{
	int i=0,len;
	SqList *p=L;
	if(p == NULL)
	{
		return ERROR;	//该链表不存在
	}
	len = ListLength_Sq(L);
	printf("\n\n\n************** output start **************\n");
	while(i < len)
	{
		printf("%d  ",p->elem[i++]);
	}
	printf("\n************** output end **************\n");
	return OK;
}

/*
输入参数:*L	待插入线性表的头结点
		   i	待插入位置(1 <= i <= ListLength(&L) + 1)
		   e	待插入数据
返回参数:ERROR	操作失败
		   OK		操作成功
函数功能:在顺序线性表L的第i个位置之前插入新元素e,L长度加1
*/
Status ListInsert_Sq(SqList	*L,int i,ElemType e)
{
	ElemType *newnode,*p,*q;
	if(i < 1 || i > L->length + 1)	return ERROR;	//i值不合法
	if(L->length >= L->listsize)
	{
		newnode = (ElemType *)realloc(L->elem, (L->listsize + LISTINCREMENT)*sizeof(ElemType));
		if(!newnode)	exit(OVERFLOW);
		L->elem = newnode;	//新的首地址不一定与原地址相同,因为为了增加空间,存储区会进行必要的移动。
		L->listsize += LISTINCREMENT;
	}
	q = L->elem + i - 1;
	for(p = L->elem + L->length - 1; p >= q; p--)
	{*(p+1) = *p;}	//插入位置及之后的元素右移
	*q = e;
	L->length++;
	return OK;
}

/*
输入参数:*L		待删除结点的链表头结点
		   i		待删除结点的位置
		   e		待删除结点的值
返回参数:ERROR	操作成功
		   OK		失败
函数功能:删除顺序线性表L中的第i个元素,并用e返回其值。
*/
Status ListDelete_Sq(SqList *L,int i,ElemType *e)
{
	ElemType *p,*q;
	if((i<1) || (i>L->length))	return ERROR;
	p = L->elem + i - 1;
	*e = *p;

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//这段程序的操作效率相对不高。
//	while(i <= L->length)
//	{
//		p++;
//		*(p-1) = *(p);
//		i++;
//	}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<



//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//下面这段程序相对上面的较高。
	q = L->elem + L->length - 1;
	for(p++; p <= q; p++)
	{*(p-1) = *p;}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

	L->length--;
	return OK;
}

/*
输入参数:*L	待查找链表的头结点
		   e	待比较元素
		   compare	数据元素比较函数,或者叫判定函数
返回参数:i	顺序线性表中第1个与e满足关系compare()的元素的位置
函数功能:返回L中第一个与e满足关系compare()的元素的位序,若这样的数据元素不存在,则返回值为0。  
*/
int LocateElem_Sq(SqList *L,ElemType e,Status (*compare)(ElemType ,ElemType ))
{
	int i=0;
	ElemType *p;
	p=L->elem;
	while(i++ <= L->length && !(*compare)(*p++,e))
	{
		//i++;
		//p++;
	}
	if(i <= L->length)	return i;
	else	return FALSE;
}


main.c

int main()
{
	ElemType dat;
	SqList L;
	InitList_Sq(&L);
	ListScanf_Sq(&L);
	ListDisp_Sq(&L);
	printf("@@@@@@@@@@@@@@@@@@@@@\n");
	
	ListInsert_Sq(&L,4,1010);
	ListDisp_Sq(&L);
	printf("@@@@@@@@@@@@@@@@@@@@@\n");
	ListDelete_Sq(&L,9,&dat);
	ListDisp_Sq(&L);
	printf("dat=%d\n",dat);

	printf("%d\n",LocateElem_Sq(&L,3,Equal));
}

 

运行输出结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值