数据结构这门课,前面学习的结构(线性表、栈、队列和串)都是线性结构,不管是顺序实现还是链式实现,在逻辑上都是一维的,也最容易理解。
然而从数组开始,逻辑结构不再局限于一维,比如我们本节要讲的数组,特指多维数组,而我们生活的世界是三维的,当维度大于 3 时,理解起来就会有点困难。
概念部分
n 维数组中所有的数据元素都必须属于同一数据类型。数组中的每个数据元素都对应于一组下标(几维即几个下标),每个下标的取值范围称为对应维度的长度。
数组一旦被定义,它的维数和维度就不再改变。因此,除了结构的初始化和销毁之外,数组只有存取元素和修改元素值的操作。
概念部分中这两行话摘自教科书,前几天在网上看到一个新闻说现在的教材有防自学机制,数据结构这门课的教材就很能防自学。上面的定义就很典型,是一点都不通俗,一点都不说人话,生怕你读了这句话明白了他在讲什么意思。
就“除了结构的初始化和销毁之外,数组只有存取元素和修改元素值的操作”这句话来说,里面的“存取元素”是不是包含了“修改元素值”?存是一个操作,取是另一个操作,存就是
set,取就是get,那“修改元素值”是不是也是set?另外像“结构的初始化和销毁”这类表达能不能改成“数组的创建和销毁”这种易于理解一点的?非得堆术语、简单问题复杂化、提高阅读理解的门槛?
如何理解多维
先举两个现实生活中的例子吧,有了这两个例子,就能很容易理解多维,能理解了多维,数组就是很简单的结构了。
第一个例子是时间,时间就是一个多维数组,年、月、日、时、分、秒就是这个多维数组的维度。其中,分和秒这两个维度的长度是 60,小时这个维度的长度是 24,日这个维度的长度是 31……
既然时间可以理解成是多维的,那任何“进制”也可以理解成多维,就拿我们最熟悉的十进制来说,个、十、百、千、万……都是维度,每个维度的长度都是“十”,并且这个多维数组中的每个元素的值都是“1”。
逻辑结构
在概念部分已经提到了,数组的操作除了创建和销毁,只有存和取。
- InitArray(&A, n, bound1, …, boundn)
- DestroyArray(&A)
- Value(A, &e, index1, …, indexn)
- Assign(&A, e, index1, …, indexn)
唯一需要注意的地方就是要注意是多维数组,所以在创建的时候需要通过参数指定是几维数组并设置各维的长度,在存和取的操作中要指定各维的下标。
物理结构
教科书中给出了数组的顺序存储实现,说白了就是用一个一维的数组来存储多维数组中的各元素。教科书在这里又定义了一个术语,数组中第一个元素的地址,称为基地址或基值。
理解十进制是多维数组后,多维数组的实现就不是难题了。比如,在InitArray的操作中,需要创建一个一维数组,那这个一维数组要创建多大的呢?这个问题可以转换成“3位数(个十百)中有几个数子?”,很明显,0~999就是1000,也就是10*10*10,也就是各维度的长度的乘积就是多维数组中元素的个数。
第二个问题,给出每一维的下标,如何确定对应的元素在一维数组中的具体位置?这个问题也可以转换成“十进制数从低到高排列,值是398的数在第几位?”,很明显,398就是第398位(从1开始数的话),398=3*(10*10)+9*10+8,其中的 10 是个位或十位的长度,3、9、8是三个维度上的下标。所以只要知道各维的下标和各维的长度,就能算出下标对应元素在一维数组中的位置。
好了,本期内容就到这里,希望通过本期的内容可以让你很容易的理解数组结构,下期见!
