《数据结构(C语言版)》数组的实现
清华大学计算机系列教材 累计发行超400万册
严蔚敏 吴伟民 编著
数据结构(C语言版)
以下是本人对该紫皮书第五章数组与广义表中5.2节的代码实现,感觉这节的代码超纲了,include了一个不知道是什么的库,说实话下面的代码运行不出来,不知道哪里报错了,以后有时间再改吧,最近比较忙可能不一定能保证日更了
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>//标准头文件,提供宏va_start、va_arg和va_end,用于存储变长参数表
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define UNDERFLOW -3
/*数组特点结构固定,维数和维界不变,故一般采用顺序存储结构表示*/
#define MAX_ARRAY_DIM 8
typedef int Status;
typedef int ElemType;
typedef struct
{
ElemType* base;//数组元素基址,由InitArray分配
int dim;//数组维数
int* bounds;//数组维界基址,由InitArray分配
int* constants;//数组映像函数常量基址,由InitArray分配
}Array;
Status InitArray(Array& A, int dim, ...);//初始化数组
Status DestoryArray(Array& A);//销毁数组
Status Value(Array A, ElemType& e, ...);
Status Assgin(Array& A, ElemType e, ...);
int main()
{
Array array;
int value;
int dim = 3; //维数3
//初始化
InitArray(array, dim, 2, 3, 4); //三个维数分别为2,3,4
printf("%d %d %d \n", array.bounds[0], array.bounds[1], array.bounds[2]);
printf("%d %d %d \n", array.constants[0], array.constants[1], array.constants[2]);
Assgin(array, 666, 1, 2, 3);
Value(array, value, 1, 2, 3);
return 0;
return 0;
}
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)
{
exit(OVERFLOW);
}
int elemtotal = 1;
va_list ap;//ap为va_list类型,是存放变长参数表信息的数组
va_start(ap, dim);//从dim后开始读取
for (int i = 0; i < dim; i++)//循环,为bounds赋值
{
A.bounds[i] = va_arg(ap, int);//从参数表中读取各个维数对应的值
if (A.bounds[i] < 0)
{
return UNDERFLOW;
}
elemtotal *= A.bounds[i];//总数=维数对应值的乘积值
}
va_end(ap);//结束参数的读取
A.base = (ElemType*)malloc(elemtotal * sizeof(ElemType));
if (!A.base)
{
exit(OVERFLOW);
}
A.constants = (int*)malloc(elemtotal * sizeof(int));
if (!A.constants)
{
exit(OVERFLOW);
}
A.constants[dim - 1] = 1;
for (int i = dim - 2; i >= 0; i--)
{
A.constants[i] = A.bounds[i + 1] * A.constants[i + 1];
}
}
Status DestoryArray(Array& 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(Array A, va_list ap, int& off) {
//若ap指示的各下标值合法,则求出该元素在A中相对地址off
off = 0;
for (int i = 0; i < A.dim; i++)
{
int ind = va_arg(ap, int);
if (ind < 0 || ind >= A.bounds[i])
{
printf("数组小标越界\n");
return 0;
}
//公式对应P92
off += A.constants[i] * ind; //每一维的小标程每一维的偏移量
}
}
//获取元素的值
Status Value(Array A, ElemType& e, ...)
{
//A是n维数组,e为元素变量,随后是n个下标值
//若各下标不超界,则e赋值为所指定的A的元素值
va_list ap;
int off;
Status result;
va_start(ap, e);
if ((result = Locate(A, ap, off)) <= 0)
{
return result;
}
e = *(A.base + off);
printf("值为:%d\n", e);
return OK;
}
//为元素赋值
Status Assgin(Array& A, ElemType e, ...)
{
//A是n维数组,e为元素变量,随后是n个下标值
//若各下标不超界,则e赋值为所指定的A的元素值
va_list ap;
int off;
Status result;
va_start(ap, e);
if ((result = Locate(A, ap, off)) <= 0)
{
return result;
}
*(A.base + off) = e;
printf("赋值为:%d成功\n", e);
return OK;
}