数据结构 数组顺序存储详细介绍

发布时间 - 2026-01-11 01:15:35    点击率:

数据结构 数组顺序存储

          最近学习数据结构,看到数组顺序存储,很是头昏,看不懂,很多东西,这里在网上找了比较详细的资料,大家好好看注释内容:

#include<stdarg.h>  
#define MAX_ARRAY_DIM 8 //假设数组维数的最大值为8 
typedef struct {
 ElemType *base;  //数组元素基址,由InitArray分配
 int dim;  //数组维数
 int *bounds;  //数组维界基址,由InitArray分配
 int *constants;  //数组映象函数常量基址,由InitArray分配
}Array;

Status InitArray(Array &A,int dim,...){//这里用的是“可变参”形参方式。它主要解决维数不定的问题。
//举例:设有4维数组,各维分别是:4,5,6,7(这些数字是随意给的),那么,调用方式:
//InitArray(ar, 4, 4, 5, 6, 7);
//ar其中,ar也是假设的变量名称, 4表示数组有4维, 4, 5, 6, 7这4个数是各维大小
//如果是5维的,那么就这样:
//InitArray(ar, 5, 第一维数,第二维数,第三维数,第四维数,第五维数);
//若维数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);
//若各维长度合法,则存入A.bounds,并求出A的元素总数elemtotal。
elemtotal=1;
va_start(ap,dim); //ap为va_list类型,是存放变长参数表信息的数组。
for (i=0;i<dim;++i){
 A.bounds[i]=va_arg(ap,int);//从这里可以看出,A.bounds数组中,存放的是各维的大小
 if (A.bounds[i]<0) return UNDERFLOW;
 elemtotal * = A.bounds[i];//各维数之积,自然是数组中元素的总个数
}
va_end(ap);
A.base=(ElemType *)malloc(elemtotal *sizeof(ElemType));//这个就是“多维数组”的存储本质:一维数组!
//用一维方式表示多维数组后(其实,从管理和使用的角度看,内存就只有一维这么一种形式),存在如何按“多维”的逻辑角度定位元素的问题。再说清楚些:假设前面所讲的4维数组,其元素用下标形式表示,范围为:(0,0,0,0)到(3,4,5,6)。对于任意下标(在有效范围内)(i1, i2, i3, i4)所对应的元素,转换到“一维”空间后,其下标应该是什么?这就是这个程序后面要处理的主要问题。
if (!A.base) exit (OVERFLOW):
//求映象函数的常数ci(i为下标),并存入A.constants[i-1],i=1,...dim。
A.constants=(int *)malloc(dim *sizeof(int));
if (!A.constants)exit (OVERFLOW);
//以前面的4维数组为例子,其中A.bounds[0]=4,A.bounds[1]=5,A.bounds[2]=6,A.bounds[3]=7。
//跟踪下面的程序:
A.constants[dim-1]=1;//A.constants[3] = 1
for (i=dim-2;i>=0;--i)//A.constants[2] = 7,A.constants[1] = 6*7,A.constants[0] = 5*6*7
 A.constants[i]=A.bounds[i+1] * A.constants[i+1];
//说到这里,这个问题就清晰了:A.constants中的元素,是帮助定位用的。比如说:对于(2,0,0,0)这个下标的元素,应该越过前面的(0,0,0,0)~(0,4,5,6)和(1,0,0,0)~(1,4,5,6)这两大块,而这两大块中的每一块都有5*6*7个元素,这正好就是A.constants[0]中所存放的数据啊!
//现在应该明白了吧!
return OK;
}

status Locate(Array A,va_list ap,int &off){
//若ap指示的各下标值合法,则求出该元素在A中相对地址off。
 off=0;
 for (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.constants[dim-1]

bounds存的就是每一维里面的个数,constants保存的是每一个维度如果下标增加1,那个对应到内存空间的下标应该增加多少。说起来比较抽象,我们假设是3维,就比较容易说清楚了,首先把3维看作有bounds[0]那么高,对于每一个0到bounds[0]-1的范围内,就是一个平面,这个平面有bounds[1]那么长,bounds[2]那么宽。那么,我们把高=0,长=0,宽=0对应到内存的第一个位置,高=0,长=0,宽=1的对应到第二个位置,那么高=0,长=1,宽=0应该放在什么位置呢?显然就是0+bounds[2]这个位置。那么高=1,长=0,宽=0的那个元素应该在哪个位置呢?显然是高=0这一个平面放完了之后的那个位置,高=0这个平面有长度*宽度那么多个元素,也就是bounds[1]*bounds[2]这么多个元素,所以高=1,长=0,宽=0这个元素就应该在0+bounds[1]*bounds[2]这个位置,对吧。假设还有第四维度,我们假设这个维度代表时间吧,那时间=0,高=0,长=0,宽=0的元素放在内存第0个位置,那么时间=1,高=0,长=0,宽=0的元素是不是应该放在0+bound[1]*bound[2]*bound[3]这个位置呢。这就是A.constants[i]=A.bounds[i+1] * A.constants[i+1];这个公式的来历。当然,我只是很简单的解释了,很多细节需要你自己考虑,因为语言表示起来太复杂了,不知道怎么表述。。。
其实你仔细看A.constants[i]=A.bounds[i+1] * A.constants[i+1];,这是一个递推公式,把它展开的话,下面我就把constants[i]简写为coni,bounds[i]简写为boni那么con i= bon[i+1]*con[i+1]=bon[i+1]*bon[i+2]*con[i+2] = bon[i+1]*bon[i+2]*bon[i+3]*con[i+3]=bon[i+1]*bon[i+2]*bon[i+3]*...*bon[dim]你看这个公式是不是就是相当于上面说的高度*长度*宽度? 刚才那个bon[dim]应该写成bon[dim-1]不过这个不影响理解。

然后我们看最后一维,例如上面例子的宽度,宽度+1是不是就正好内存地址+1呢?于是对应宽度这个最后的维度,每次地址只需+1就能访问下一个元素,因此bon[dim-1]也就是最后一维的,是不是就应该等于1呢。。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# 数据结构  # 数组顺序存储  # C语言数据结构  # 数组  # 数据结构之数组Array实例详解  # C语言 数据结构之连续存储数组的算法  # 多维  # 的是  # 求出  # 放在  # 多个  # 这就是  # 映象  # 组中  # 应到  # 有一  # 这一  # 都有  # 就能  # 只需  # 你看  # 说到  # 这个问题  # 你自己  # 把它 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制  浏览器如何快速切换搜索引擎_在地址栏使用不同搜索引擎【搜索】  Laravel如何构建RESTful API_Laravel标准化API接口开发指南  javascript日期怎么处理_如何格式化输出  如何快速生成ASP一键建站模板并优化安全性?  Laravel怎么上传文件_Laravel图片上传及存储配置  Mybatis 中的insertOrUpdate操作  JS中页面与页面之间超链接跳转中文乱码问题的解决办法  Laravel安装步骤详细教程_Laravel环境搭建指南  Laravel中Service Container是做什么的_Laravel服务容器与依赖注入核心概念解析  高防服务器如何保障网站安全无虞?  高端智能建站公司优选:品牌定制与SEO优化一站式服务  如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框  如何用AWS免费套餐快速搭建高效网站?  Laravel如何使用Blade模板引擎?(完整语法和示例)  Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用  Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程  python中快速进行多个字符替换的方法小结  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  SQL查询语句优化的实用方法总结  Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  如何构建满足综合性能需求的优质建站方案?  网站建设整体流程解析,建站其实很容易!  UC浏览器如何设置启动页 UC浏览器启动页设置方法  Laravel API资源(Resource)怎么用_格式化Laravel API响应的最佳实践  怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?  如何获取免费开源的自助建站系统源码?  高性能网站服务器部署指南:稳定运行与安全配置优化方案  如何在阿里云购买域名并搭建网站?  Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】  重庆市网站制作公司,重庆招聘网站哪个好?  哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?  电视网站制作tvbox接口,云海电视怎样自定义添加电视源?  Laravel如何实现密码重置功能_Laravel密码找回与重置流程  Linux系统命令中screen命令详解  Android仿QQ列表左滑删除操作  Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】  详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南  零基础网站服务器架设实战:轻量应用与域名解析配置指南  如何快速搭建二级域名独立网站?  Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】  详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)  Laravel如何保护应用免受CSRF攻击?(原理和示例)  清除minerd进程的简单方法  如何快速搭建个人网站并优化SEO?  Laravel辅助函数有哪些_Laravel Helpers常用助手函数大全  Laravel N+1查询问题如何解决_Eloquent预加载(Eager Loading)优化数据库查询  Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)  如何打造高效商业网站?建站目的决定转化率