5. 数组与广义表

合集下载

数据结构第五章 数组与广义表

数据结构第五章 数组与广义表
an-1,n-1
压缩存储方法:只需要存储下三角 (含对角线)上的元素。可节省一 半空间。
可以使用一维数组Sa[n(n+1)/2]作为n阶对称矩阵A的存 储结构,且约定以行序为主序存储各个元素,则在Sa[k]和矩
阵元素aij之间存在一一对应关系: (下标变换公式)
i(i+1)/2 + j 当i≥j k = j(j+1)/2 + i 当i<j
q = cpot[col];
T.data[q].i = M.data[p].j; T.data[q].j = M.data[p].i; T.data[q].e = M.data[p].e; ++cpot[col]; }
分析算法FastTransposeSMatrix的时间 复杂度:
for (col=1; col<=M.nu; ++col) … … for (t=1; t<=M.tu; ++t) … … for (col=2; col<=M.nu; ++col) … … for (p=1; p<=M.tu; ++p) … …
//对当前行中每一个非零元

brow=M.data[p].j;

if (brow < N.nu ) t = N.rpos[brow+1];
M
else { t = N.tu+1 }

for (q=N.rpos[brow]; q< t; ++q) { ccol = N.data[q].j; // 乘积元素在Q中列号
一、三元组顺序表
对于稀疏矩阵,非零元可以用三元组表示, 整个稀疏矩阵可以表示为所有非零元的三元组所 构成的线性表。例如:

第5章数组与广义表

第5章数组与广义表


5.2 数组的顺序表示和实现

特点:用一组地址连续的存储单元按照某种规则存放数组 中的数据元素。 两种规则(顺序存储方式):


以行序为主(低下标优先)—将数组元素按行排列,第 i+1个行向量紧接在第i个行向量后。如:PASCAL、C。 以列序为主(高下标优先)—将数组元素按列排列,第 j+1个列向量紧接在第j个列向量后。如:FORTRAN。
am-1,0 a01 a11 …… am-1,1
……
按 列 序 为 主 序
a0,n-1 a1,n-1
……
am-1,n-1 am-1,n-1 ?A[2][3][2]以行序为主存储,写出其元素存放的先后顺序
5.2 数组的顺序表示和实现


计算数组任一元素(a j1 j2 ... jn )的地址需要的三要素: ①数组的起始地址(即基地址) ②数组维数和各维的长度; ③数组中每个元素所占的存储单元 已知二维数组Ab1*b2,每个元素占L个存储单元, LOC(0,0)是 数组第一个元素的起始地址,以行序为主存储,求LOC(i,j)。
N维数组数据元素存储地址计算
1、数组M[1..10][-1..6][[0..3],起始地址是1000,每个元素占3个 存储单元,数组元素个数是 ,M[2][4][2]的地址是 。 2、数组A[0 .. 8][1 .. 10]的成员由6个字节组成,存放a要 个字 节,a的第8行第5列占 个字节。按行序a[8][5]与按列序 起始地址相同。 (10-1+1)*(6-(-1)+1)*(3-0+1)=320 LOC(M[2][4][2])=1000+[(i-1)*b2*b3+(j-(-1))*b3+k]*l =1000+[32*(2-1)+4*(4+1)+2]*3=1162 LOC(a[8][5])=a(起始地址)+(i*n+(j-1))*l =a+(8*10+4)*6=a+504, LOC(a[3][10])=a(起始地址)+((j-1)*m+i)*l =a+(9*9+3)*6=a+504。

第五章 数组与广义表

第五章 数组与广义表

第五章数组、特殊矩阵和广义表本章介绍的数组与广义表可视为线性表的推广,其特点是数据元素仍然是一个表。

本章讨论多维数组的逻辑结构和存储结构、特殊矩阵、矩阵的压缩存储、广义表的逻辑结构和存储结构等。

5.1 多维数组5.1.1 数组的逻辑结构数组是我们很熟悉的一种数据结构,它可以看作线性表的推广。

数组作为一种数据结构其特点是结构中的元素本身可以是具有某种结构的数据,但属于同一数据类型,比如:一维数组可以看作一个线性表,二维数组可以看作“数据元素是一维数组”的一维数组,三维数组可以看作“数据元素是二维数组”的一维数组,依此类推。

图5.1是一个m行n 列的二维数组。

标识,因此,在数组上不能做插入、删除数据元素的操作。

通常在各种高级语言中数组一旦被定义,每一维的大小及上下界都不能改变。

在数组中通常做下面两种操作:(1)取值操作:给定一组下标,读其对应的数据元素。

(2)赋值操作:给定一组下标,存储或修改与其相对应的数据元素。

我们着重研究二维和三维数组,因为它们的应用是广泛的,尤其是二维数组。

5.1.2 数组的内存映象现在来讨论数组在计算机中的存储表示。

通常,数组在内存被映象为向量,即用向量作为数组的一种存储结构,这是因为内存的地址空间是一维的,数组的行列固定后,通过一个映象函数,则可根据数组元素的下标得到它的存储地址。

对于一维数组按下标顺序分配即可。

对多维数组分配时,要把它的元素映象存储在一维存储器中,一般有两种存储方式:一是以行为主序(或先行后列)的顺序存放,如BASIC、PASCAL、COBOL、C等程序设计语言中用的是以行为主的顺序分配,即一行分配完了接着分配下一行。

另一种是以列为主序(先列后行)的顺序存放,如FORTRAN语言中,用的是以列为主序的分配顺序,即一列一列地分配。

以行为主序的分配规律是:最右边的下标先变化,即最右下标从小到大,循环一遍后,右边第二个下标再变,…,从右向左,最后是左下标。

以列为主序分配的规律恰好相反:最左边的下标先变化,即最左下标从小到大,循环一遍后,左边第二个下标再变,…,从左向右,最后是右下标。

数据结构第5章

数据结构第5章

第5章:数组和广义表 1. 了解数组的定义;填空题:1、假设有二维数组A 6×8,每个元素用相邻的6个字节存储,存储器按字节编址。

已知A 的起始存储位置(基地址)为1000,则数组A 的体积(存储量)为 288 B ;末尾元素A 57的第一个字节地址为 1282 。

2、三元素组表中的每个结点对应于稀疏矩阵的一个非零元素,它包含有三个数据项,分别表示该元素的 行下标 、 列下标 和 元素值 。

2. 理解数组的顺序表示方法会计算数组元素顺序存储的地址;填空题:1、已知A 的起始存储位置(基地址)为1000,若按行存储时,元素A 14的第一个字节地址为 (8+4)×6+1000=1072 ;若按列存储时,元素A 47的第一个字节地址为 (6×7+4)×6+1000)=1276 。

(注:数组是从0行0列还是从1行1列计算起呢?由末单元为A 57可知,是从0行0列开始!) 2、设数组a[1…60, 1…70]的基地址为2048,每个元素占2个存储单元,若以列序为主序顺序存储,则元素a[32,58]的存储地址为 8950 。

答:不考虑0行0列,利用列优先公式: LOC(a ij )=LOC(a c 1,c 2)+[(j-c 2)*(d 1-c 1+1)+i-c 1)]*L 得:LOC(a 32,58)=2048+[(58-1)*(60-1+1)+32-1]]*2=8950选择题:( A )1、假设有60行70列的二维数组a[1…60, 1…70]以列序为主序顺序存储,其基地址为10000,每个元素占2个存储单元,那么第32行第58列的元素a[32,58]的存储地址为 。

(无第0行第0列元素)A .16902B .16904C .14454D .答案A, B, C 均不对 答:此题(57列×60行+31行)×2字节+10000=16902( B )2、设矩阵A 是一个对称矩阵,为了节省存储,将其下三角部分(如下图所示)按行序存放在一维数组B[ 1, n(n-1)/2 ]中,对下三角部分中任一元素a i,j (i ≤j), 在一维数组B 中下标k 的值是:A .i(i-1)/2+j-1B .i(i-1)/2+jC .i(i+1)/2+j-1D .i(i+1)/2+j3、从供选择的答案中,选出应填入下面叙述 ? 内的最确切的解答,把相应编号写在答卷的对应栏内。

第5章数组和广义表

第5章数组和广义表
//L=1,指针的增减以元素的大小为单位 For(i=dim-2;i>0;--i)
A.contants[i]=A.bounds[i+1]*A.constants[i+1]; return ok; }
第5章 数组和广义表
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.contants) return ERROR; free(A.contants) A.contants=NULL; return ok;
(3) Value(A,&e, index1, …, indexn): 若下标合法,则 用e返回数组A中由index1, …, indexn所指定的元素的值。
(4) Assign(&A,e,indexl,…indexn):若各下标不超界, 则将e赋值为所指定的A的元素值,并返回OK。 。
第5章 数组和广义表
三维数组A(1..r , 1..m , 1..n)可以看成是r个m×n的二维数组,
如图5.5所示。
n
m n
r j- 1
m
k- 1
图5.5 三维数组看成r个m×n的二维数组
第5章 数组和广义表
假定每个元素占一个存储单元,采用以行为主序的方法存 放,即行下标r变化最慢, 纵下标n变化最快。 首元素a111的地 址为Loc[1, 1, 1],求任意元素aijk的地址。
第5章 数组和广义表
以上我们以二维数组为例介绍了数组的结构特性,实际 上数组是一组有固定个数的元素的集合。也就是说,一旦定 义了数组的维数和每一维的上下限,数组中元素的个数就固 定了。 例如二维数组A3×4,它有3行、4列,即由12个元素组 成。由于这个性质,使得对数组的操作不像对线性表的操作 那样可以在表中任意一个合法的位置插入或删除一个元素。 对于数组的操作一般只有两类:

数据结构第5章数组与广义表

数据结构第5章数组与广义表
0 0 3 0 1 0 1 2 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 2 0
一个稀疏矩阵里存在大量的零元素,若 以常规方法,即以二维数组来存储稀疏矩 阵时产生如下问题: 1) 零值元素占了很多空间; 2) 如果进行计算,则会进行很多和零值 的运算,如是除法,还需判别除数是否为 零。
2 三角矩阵 以主对角线划分,三角矩阵有上三角 和下三角两种。如图所示。其中(a)图为下 三角矩阵:主对角线以上均为同一个常 数;(b)图为上三角矩阵,主对角线以下均 为同一个常数。
(1) 下三角矩阵 三角矩阵中的重复元素c可共享一个 存储空间,其余的元素正好有n(n+1)/2 个,因此,三角矩阵可压缩存储到向量 SA[0…n(n+1)/2]中,其中c存放在向量的 最后1个分量SA[n(n+1)/2]中。 该存储方式可节约n*(n-1)/2-1个存储 单元。
传统矩阵的转置算法为: for(col=1; col<=n ;++col) for(row=0 ; row<=m ;++row) b[col][row]=a[row][col] ;
时间复杂度为O(n×m) 当非零元素的个数tn和m×n同数量级时,算法 TransMatrix的时间复杂度为O(m×n2)。
以“行优先顺序”存储: (1) 第1行中的每个元素对应的(首)地址是: LOC[a1j]=LOC[a11]+(j-1) ×L (2) 第2行中的每个元素对应的(首)地址是: LOC[a2j]=LOC[a11]+n×L +(j-1) ×L (3) 第m行中的每个元素对应的(首)地址是: LOC[amj]=LOC[a11]+(m-1) n×L +(j-1) ×L

数据结构数组和广义表

数据结构数组和广义表

数据结构05数组与广义表数组与广义表可以看做是线性表地扩展,即数组与广义表地数据元素本身也是一种数据结构。

5.1 数组地基本概念5.2 数组地存储结构5.3 矩阵地压缩存储5.4 广义表地基本概念数组是由相同类型地一组数据元素组成地一个有限序列。

其数据元素通常也称为数组元素。

数组地每个数据元素都有一个序号,称为下标。

可以通过数组下标访问数据元素。

数据元素受n(n≥1)个线性关系地约束,每个数据元素在n个线性关系地序号 i1,i2,…,in称为该数据元素地下标,并称该数组为n维数组。

如下图是一个m行,n列地二维数组A矩阵任何一个元素都有两个下标,一个为行号,另一个为列号。

如aij表示第i行j列地数据元素。

数组也是一种线性数据结构,它可以看成是线性表地一种扩充。

一维数组可以看作是一个线性表,二维数组可以看作数据元素是一维数组(或线性表)地线性表,其一行或一列就是一个一维数组地数据元素。

如上例地二维数组既可表示成一个行向量地线性表: A1=(a11,a12,···,a1n)A2=(a21,a22, ···,a2n)A=(A1,A2, ···,Am) ············Am=(am1,am2, ···,amn)也可表示成一个列向量地线性表:B1=(a11,a21,···,am1)B2=(a12,a22, ···,am2)A=(B1,B2, ···,Bm) ············Bn=(a1n,a2n, ···,amn)数组地每个数据元素都与一组唯一地下标值对应。

第5章 数组和广义表总结

第5章 数组和广义表总结

0603
2090
B5×4 = 0 8 0 0
0000
row col val
4000
0 12
0 44
1 06
1 28
2 19
3 03
现在,要通过A的 三元组表求其转置 矩阵B的三元组表。
row col val
0 16 0 33 1 02 1 29 2 18 4 04
16
三元组表的转置
方法1:设矩阵A是m行、n列、t个非0元素 从头到尾扫描A,将第0列的元素依次放入B(行号列号互换); 从头到尾扫描A,将第1列的元素依次放入B(行号列号互换); ...... 从头到尾扫描A,将第n-1列的元素依次放入B(行号列号互换); 扫描A几趟? 矩阵A的列数n
}tritype;
typedef struct { //三元组表
tritype data[MAXSIZE]; //三元组表存储空间
int mu, nu, tu;
//原矩阵的行数、列数、非0元素个数
}Tsmtype, *Tsmlink;
//三元组表说明符
14
三元组表
例 5.3 矩阵的转置。 求矩阵A的转置矩阵B,算法很简单:
ArrayInit(&A, n, d1, d2, ..., dn) ArrayDestroy(&A)
ArrayGet(A, i1, ..., in, &e)
ArrayAssign(&A, i1, ..., in, e) }ADT Array;
数组的基本操作一般不包括插入和删除
4
5.2 数组的存储结构
存储空间是在程序执行时动态分配的
n维数组A[u1][u2]…[un]
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
问题:计算机的内存结构是一维(线性)地址结构, 对于多维数组,将其存放(映射)到内存一维结构时,有 个次序约定问题。即必须按某种次序将数组元素排成一 列序列,然后将这个线性序列存放到内存中。 二维数组是最简单的多维数组,以此为例说明多维 数组存放(映射)到内存一维结构时的次序约定问题。

… a2n
第 2 行
… am2
第 2 列
(a)
二维数组的表示形式

am1 am2
… Amn

第 m 行

a1m a2m
… amn

第 n 列
二维数组及其顺序存储图例形式


(c) 列优先顺序存储
(b) 行优先顺序存储

设有二维数组A=(aij)mn,若每个元素占用的存储单元数为 l(个),LOC[a11]表示元素a11的首地址,即数组的首地址。 1 以“行优先顺序”存储
k=i(i-1)/2+j-1 i≧ j
若i<j:则aij是在上三角矩阵中。因为aij=aji,在向量sa中保 存的是aji 。依上述分析可得:
k=j(j-1)/2+i-1 i<j 对称矩阵元素ai j保存在向量sa中时的下标值k与(i,j)之间 的对应关系是:
i(i-1)/2+j-1
K=
当i≧j时
对称矩阵的压缩存储示例

若i≧j:ai j在下三角形中,直接保存在sa中。ai j之前的i-1行 共有元素个数: 1+2+…+(i-1)=i(i-1)/2
而在第i行上,ai j之前恰有j-1个元素,因此,元素ai j保存在向量 sa中时的下标值k之间的对应关系是:
设用一维数组(向量)sa[1…n(n+1)/2]存储n阶对称矩 阵,如图所示。为了便于访问,必须找出矩阵A中的元素的下标 值(i,j)和向量sa[k]的下标值k之间的对应关系。
k sa
1 a11
2 a21
3 a22
4 a31
… a32 a33 …
n(n-1)/2 … n(n+1)/2 an1 an2 … ann
j(j-1)/2+i-1
根据上述的下标对应关系,对于矩阵中的任意元素aij,均可 在一维数组sa中唯一确定其位置k;反之,对所有 k=1,2, …,n(n+1)/2,都能确定sa[k]中的元素在矩阵中的位置 (i,j)。 称sa[0…n(n+1)/2]为n阶对称矩阵A的压缩存储。
00 10 11 20 21 22 30 31 32 33
k= i(i-1)/2+j-1 if i>=j j(j-1)/2+i-1 if i<j
1 k= 0
2 1
8 2
3 3
6 4
9 4 5 6
5 7
7 8
0 9

2
三角矩阵
以主对角线划分,三角矩阵有上三角和下三角两种。
(2) 第2列中的每个元素对应的(首)地址是:
由此可知,二维数组中任一元素aij的(首)地址是:
(5-1)

5.2、矩阵的压缩存储
在科学与工程计算问题中,矩阵是一种常用的数学 对象,在高级语言编程时,通常将一个矩阵描述为一个 二维数组。这样,可以对其元素进行随机存取,各种矩 阵运算也非常简单。
◆ 数组中的数据元素具有相同数据类型。
◆ 数组是一种随机存取结构,给定一组下标,就可以访问与 其对应的数据元素。
◆ 数组中的数据元素个数是固定的。

数组的抽象数据类型定义
1 抽象数据类型定义
ADT Array{
数据对象:ji= 0,1,…,bi-1 , 1,2, …,n ;

5.1、数组
数组是一组偶对(下标值,数据元素值)的集合。在 数组中,对于一组有意义的下标,都存在一个与其对应 的值。一维数组对应着一个下标值,二维数组对应着两 个下标值,如此类推。
数组是由n(n>1)个具有相同数据类型的数据元素 a1,a2,…,an组成的有序序列,且该序列必须存储在 一块地址连续的存储单元中。
通常有两种顺序存储方式
⑴ 行优先顺序(Row Major Order) :将数组元素按行排列, 第i+1个行向量紧接在第i个行向量后面。对二维数组,按行优 先顺序存储的线性序列为: a11,a12,…,a1n, a21,a22,…a2n ,……, am1,am2,…,amn
PASCAL、C是按行优先顺序存储的,如图5-2(b)示。 ⑵ 列优先顺序(Column Major Order) :将数组元素按列 向量排列,第j+1个列向量紧接在第j个列向量之后,对二维数 组,按列优先顺序存储的线性序列为: a11,a21,…,am1, an1,an2,…,anm a12,a22,…am2, ……,
基本操作: ……
} ADT Array

由上述定义知,n维数组中有b1b2 … bn个数据元素, 每个数据元素都受到n维关系的约束。 2 直观的n维数组
以二维数组为例讨论。将二维数组看成是一个定长的线性表, 其每个元素又是一个定长的线性表。 设二维数组A=(aij)mn,则 A=(α1,α2,…,αp) (p=m或n) 1≦j≦n 1≦i≦m 其中每个数据元素αj是一个列向量(线性表) : αj =(a1j ,a2j ,…,amj)
⑴ 第1行中的每个元素对应的(首)地址是:
LOC[a1j]=LOC[a11]+(j-1)l j=1,2, …,n (2) 第2行中的每个元素对应的(首)地址是:
LOC[a2j]=LOC[a11]+nl +(j-1)l
………
j=1,2, …,n
⑶ 第m行中的每个元素对应的(首)地址是: LOC[amj]=LOC[a11]+(m-1)nl +(j-1)l j=1,2, …,n
D = { aj1j2…jn | n>0称为数组的维数,bi是数组第i维的 长度,ji是数组元素第i维的下标,aj1j2…jn∈ElemSet }
数据关系:R = {R1, R2, …, Rn} Ri={<aj1j2 …ji…jn , aj1j2 …ji+1…jn>|0≦jk≦bk-1 , 1≦k≦n且k≠i,0≦ji≦bi-2, aj1j2 …ji+1…jn∈D }
第五章 数组与广义表

第5章 数组和广义表
数组是一种人们非常熟悉的数据结构,几乎所 有的程序设计语言都支持这种数据结构或将这种数据 结构设定为语言的固有类型。数组这种数据结构可以 看成是线性表的推广。
科学计算中涉及到大量的矩阵问题,在程序 设计语言中一般都采用数组来存储,被描述成一个二 维数组。但当矩阵规模很大且具有特殊结构(对角矩阵、 三角矩阵、对称矩阵、稀疏矩阵等),为减少程序的时 间和空间需求,采用自定义的描述方式。 广义表是另一种推广形式的线性表,是一种 灵活的数据结构,在许多方面有广泛的应用。
ann
对称矩阵示例

对称矩阵中的元素关于主对角线对称,因此,让每一对对 称元素aij和aji(i≠j)分配一个存储空间,则n2个元素压缩存储 到n(n+1)/2个存储空间,能节约近一半的存储空间。
不失一般性,假设按“行优先顺序”存储下三角形(包括对角 线)中的元素。
上三角矩阵的下三角(不包括主对角线)中的元素均为常数 c(一般为0)。下三角矩阵正好相反,它的主对角线上方均为常数
a11 a12 … a1n c … c a22 … a2n … …
a11
a21 … an1
c
… c
a22 … c … …
c … ann
an2 … ann
三角矩阵中的重复元素c可共享一个存储空间,其余的元素正好 有n(n+1)/2个,因此,三角矩阵可压缩存储到向量sa[0…n(n+1)/2]中, 其中c存放在向量的最后一个分量中。 上三角矩阵元素ai j保存在向量sa中时的下标值k与(i,j)之间的对 应关系是:

由此可知,二维数组中任一元素aij的(首)地址是:
LOC[aij]=LOC[a11]+[(i-1)n +(j-1)]l i=1,2, …,m j=1,2, …,n (5-1)
根据(5-1)式,对于三维数组A=(aijk)mnp,若每个元素占 用的存储单元数为l(个),LOC[a111]表示元素a111的首地址, 即数组的首地址。以“行优先顺序”存储在内存中。 三维数组中任一元素aijk的(首)地址是:
或是一个行向量:
αi =(ai1 ,ai2 ,…,ain)

a11 a12 … a1n a21 a22 … a2n A= … … … … … am1 am2 … amn
(a) 矩阵表示形式
a11 a12 … a1n a21 a22 … a2n A= …………… am1 am2 … amn
列向量的一维数组形式
(b)
A=
a11 a21 ┆ am1
(c)
a12 a22 ┆ ┆ ┆ am2 ┆
a1n a2n ┆ amn
行向量的一维数组形式
数组的顺序表示和实现

数组一般不做插入和删除操作,也就是说,数组一 旦建立,结构中的元素个数和元素间的关系就不再发生 变化。因此,一般都是采用顺序存储的方法来表示数组。
+ (b3…bn)(j2-1)+ …
+ bn(jn-1-1)+ (jn-1)] l

2
以“列优先顺序”存储
⑴ 第1列中的每个元素对应的(首)地址是: LOC[aj1]=LOC[a11]+(j-1)l LOC[aj2]=LOC[a11]+ml +(j-1)l ……… ⑶ 第n列中的每个元素对应的(首)地址是: LOC[ajn]=LOC[a11]+ (n-1)ml +(j-1)l LOC[aij]=LOC[a11]+[(i-1)m+(j-1)]l i=1,2, …,n j=1,2, …,m j=1,2, …,m j=1,2, …,m j=1,2, …,m
相关文档
最新文档