数据结构:数组的顺序存储实现

/***********************************************************************

				程序功能: 数组的顺序存储实现

************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>   //标准头文件,提供宏va_start , va_arg, va_end
					//用于存取变长参数
#define ERROR 0
#define OVERFLOW -2
#define UNDERFLOW -1
#define OK 1
#define MAX_ARRAY_DIM 8   //假设数组维数的最大值为8
typedef int ElemType;
typedef int Status;
typedef struct  
{
	ElemType *base;  //数组元素基址,由InitArray分配;
	int dim;       //数组维数
	int *bounds;     //数组维界基址, 由InitArray分配 
	int *constants;   //数组映像函数常量基址,由InitArray分配 
}Array;

Status InitArray(Array &A, int dim, ...)
{
	if(dim < 1 || dim > MAX_ARRAY_DIM)
		return ERROR;
	A.dim = dim;
	A.bounds = (int *) malloc (dim*sizeof(int));
	if(!A.bounds)
		return OVERFLOW;
	int elemTotal =1;   //存放元素的总个数
	va_list arg_ptr;   //存放变长参数表信息的数组
	va_start(arg_ptr,dim);  //第二个参数是第一个可变参数的前一个参数,固定的
	for(int i = 0; i < dim; ++i)
	{
		A.bounds[i] = va_arg(arg_ptr, int);//用va_arg返回可变的参数,并赋值给整数A.bounds[i].
							//va_arg的第二个参数是你要返回的参数的类型,这里是int型.
		if(A.bounds[i] < 0)
			return UNDERFLOW;
		elemTotal *= A.bounds[i];  
	}
	va_end(arg_ptr);
	A.base = (ElemType *) malloc (elemTotal * sizeof(ElemType));
	if(!A.base)
		return OVERFLOW;
	A.constants = (int *) malloc (dim * sizeof(int));
	if(!A.constants)
		return OVERFLOW;
	A.constants[dim - 1] = 1;//L=1,指针的增减以元素的大小为单位
	for(int index = dim -2; index >= 0; --index)
	{
		A.constants[index] = A.constants[index + 1] * A.bounds[index + 1];
	}

	return OK;

}

Status DestroyArray(Array &A)
{
	//销毁数组A
	if(!A.base) return ERROR;
	free(A.base);
	A.base = NULL;
	if(!A.bounds) return ERROR;
	free(A.bounds);
	A.bounds = NULL;
	if(!A.constants) return ERROR;
	free (A.constants);
	A.constants = NULL;

	return OK;
}

Status Locate(const Array &A, va_list ap, int &off)
{
	//若ap指示的各下标值合法,则求出该元素在A中相对地址off
	off = 0;
	int index;
	for(int i = 0; i < A.dim; ++i)
	{
		index = va_arg(ap, int);
		if(index < 0 || index >= A.bounds[i])
			return OVERFLOW;
		off += A.constants[i] * index;
	}
	return OK;
}

Status Value (const Array &A, ElemType *e, ...)
{
	//A是n维数组,e为元素变量,随后是n个下标值
	//若各下标不越界,则e赋值为所指定的A的元素值,并返回OK
	va_list ap;
	va_start(ap, e);
	int result;
	int off;
	if((result = Locate(A,ap,off)) <= 0)
		return result;
	*e = *(A.base + off);
	va_end(ap);
	return OK;
}

Status Assign(Array &A, ElemType e, ...)
{
	//A是n维数组,e为元素变量,随后是n个下标值
	//若下标不越界,则将e的值赋给所指定的A的元素,并返回OK
	va_list ap;
	va_start(ap, e);
	int off;
	int result;
	if((result = Locate(A, ap, off)) <= 0)
		return result;
	*(A.base + off) = e;
	va_end(ap);
	return OK;
}


int main()
{
	Array A;
	int testArray[2][3] = {{1, 2, 3},{4, 5, 6}};
	InitArray(A,2,2,3);
	printf("A.dim = %d\n",A.dim);
	printf("各维的长度是:\n");
	for(int index = 0; index < A.dim; ++index)
	{
		printf("%d\t",A.bounds[index]);
	}
	
	printf("\n数组的常量基址是:\n");
	for(index = 0; index < A.dim; ++index)
	{
		printf("%d\t",A.constants[index]);
	}
	printf("\n");

	for(int i = 0; i < 2; ++i)
	{
		for(int j=0; j < 3; ++j)
		{
			Assign(A, testArray[i][j], i, j); //对数组进行赋值
		}
	}

	int value;
	printf("创建的数组中的元素为:\n");
	for(i = 0; i < 2; ++i)
	{
		for(int j = 0; j < 3; ++j)
		{
			Value(A, &value,i,j);
			printf("%d\t",value);
		}
		printf("\n");
	}

	printf("按照数组的线性序列输出元素,即利用基址地址输出元素:\n");
	for( i = 0; i < 2 * 3; i++)
	{
		printf("第%d个元素=%3d\t",i+1,A.base[i]);
		if( (i+1) % 3 == 0 )
			printf("\n");
	 }
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值