数据结构-数组

版权声明:转载请注明出处。 https://blog.csdn.net/baidu_38304645/article/details/82950915

无论在数值计算亦或是非数值计算,数组均有广泛的运用。因此,绝大多数 高级语言都将数组设为固有数据类型,

数组可看做普通线性表的推广,普通数组的各项操作都不会引起元素的插入或删除,故数组使用顺序存储结构。

假设每个数据元素占L个存储单元,则二维数组A中任一元素a[i][j]的存储位置可以表示为

LOC(i,j)=LOC(0,0)+(b2*i+j)L

LOC(i,j)是a[i][j]的存储位置,LOC(0,0)是a00的存储位置,即二维数组A的起始存储位置,也称为基地址或基址。

推广到一般情况:

LOC(j1,j2,...jn)=LOC(0,0,...0) + \sum ciji

求和公式即为n维数组的映像函数。通过它可以得到元素在数组中的地址。

首先是辅助宏的定义:

#include <stdarg.h> //标准头文件 ,提供宏va_start va_arg va_end
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1
#define UNDERFLOW -2
#define MAX_ARRAY_DIM 8 //假设数组维数最大是8
va_list ap;//定义ap为va_list类型 是存放变长参数表信息的数组

数组的存储结构定义:

typedef struct{
    ElemType *base;  //数组元素基址 由InitArray分配
    int dim; //数组维数
    int *bounds;//数组维界基址 由InitArray分配
    int *constants; //数组映像函数常量基址 由InitArray分配
}Array;

若维数dim和各维长度合法 则构造函数相应的数组A 并返回OK。

Status InitArray(Array &A,int dim,...){
	//若维数dim和各维长度合法 则构造函数相应的数组A 并返回OK 
    if(dim<1||dim>MAX_ARRAY_DIM)
       return ERROR;
    A.dim=dim;  
    A.bounds=(int *)malloc(dim*sizeof(int));
    if(!A.bounds) //存储分配失败
       exit(OVERFLOW);
    int elemtotal=1,i; 
    va_start(ap,dim); //开启ap 从dim的下一个参数为第一个参数
	for(i=0;i<dim;i++){   //若各维度合法 存入A.bounds 并求出元素总数elemtotal
       A.bounds[i]=va_arg(ap,int); //不断找下一个参数类型为int的参数
       if(A.bounds[i]<0)
          return UNDERFLOW;
       elemtotal*=A.bounds[i];
	} 
    va_end(ap);//关闭ap
    A.base=(ElemType *)malloc(elemtotal*sizeof(ElemType));
    if(!A.base)//存储分配失败
       exit(OVERFLOW);
    A.constants=(int *)malloc(dim*sizeof(int));
 //求映像函数的常数 并存入A.constans[i-1],i=1...dim;
    if(!A.constants)
       exit(OVERFLOW); //存储分配失败
    A.constants[dim-1]=1;
    for(i=dim-2;i>=0;i--)
        A.constants[i]=A.bounds[i+1]*A.constants[i+1];
    return OK;
}

销毁数组A.

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;
}

若ap指示的下标值合法 则求出该元素在A中相对位置off.

Status Locate(Array A,va_list ap,int &off){
	//若ap指示的下标值合法 则求出该元素在A中相对位置off
    int ind;
    off=0;
    for(int i=0;i<A.dim;i++){
       ind=va_arg(ap,int);//获取当前参数
       if(ind<0||ind>=A.bounds[i]) //参数不合法
          return OVERFLOW;
       off+=A.constants[i]*ind;//合法地址改变
	} 
    return OK;
} 

A是n维数组e是元素变量 随后是n个下标值,若各下标不越界 则e赋值为所指定的A的元素值 并返回OK..

Status Value(Array A,ElemType *e,...){ 
    //VC中 之前的形参不能用引用(怪不得老是测试失败)
	//A是n维数组e是元素变量 随后是n个下标值
	//若各下标不越界 则e赋值为所指定的A的元素值 并返回OK
    int result,off;
    va_start(ap,e);
    if((result=Locate(A,ap,off))<=0) //如果参数下标有不合法
       return result;
    *e=*(A.base+off);//否则传回e
    return OK;
}

A是n维数组 e为元素变量 随后是n个下标值,若下标不越界 则将e的值赋给所指定的A的元素 并返回OK

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

猜你喜欢

转载自blog.csdn.net/baidu_38304645/article/details/82950915