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

压缩存储方法:只需要存储下三角 (含对角线)上的元素。可节省一 半空间。
可以使用一维数组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中列号
一、三元组顺序表
对于稀疏矩阵,非零元可以用三元组表示, 整个稀疏矩阵可以表示为所有非零元的三元组所 构成的线性表。例如:
数组和广义表

InitArray(&A, n, bound1, ..., boundn) 操作结果:若维数 n 和各维长度合法,
则构造相应的数组A,并 返回OK。
2013年7月14日星期日
DestroyArray(&A) 操作结果:销毁数组A。
2013年7月14日星期日
Value(A, &e, index1, ..., indexn) 初始条件:A是n维数组,e为元素变量, 随后是n 个下标值。 操作结果:若各下标不超界,则e赋值为
2013年7月14日星期日
a
a1 11 a1 21 a1 31 a1 41
a
三维数组元素的标号由三个数字表示,即行、列、纵三个 方向。a142 表示第1行,第4列,第2纵的元素。如果对A3×4×2
(下标从1开始)采用以行为主序的方法存放,即行下标变
化最慢,纵下标变化最快,则顺序为: a111,a112,a121,a122, …,a331,a332,a341,a342 采用以列为主序的方法存放, 即纵下标变化最慢, 行下 标变化最快, 则顺序为:
同理,三维数组最多可有三个直接前驱和三个直接后继, 三维以上数组可以作类似分析。因此,可以把三维以上 的数组称为多维数组,多维数组可有多个直接前驱和多 个直接后继,故多维数组是一种非线性结构。
2013年7月14日星期日
数组的抽象类型定义
ADT Array { 数据对象: D={aj ,j , ...,,j ,j | ji =0,...,bi -1, i=1,2,..,n } 数据关系: R={R1, R2, ..., Rn} Ri={<aj ,... j ,... j , aj , ...j +1, ...j > | 0 jk bk -1, 1 k n 且k i, 0 ji bi -2, i=2,...,n }
《数据结构——用C语言描述(第二版)》第5章 数组和广义表

第五章 数组和广义表
在压缩存储时,矩阵中值相同的元素C可共享一个存储空间,元素 为零则可不必分配空间,而其余的元素有 n(n+1)/2个,因此三角矩阵 可用一维数组M[n×(n+1)/2+1]来存储,其中常数C放在数组的最后一 个下标变量中。
假设A和B矩阵分别用matrix型指针变量a和b表示,矩阵的转置可以 按以下进行:由于B的行是A的列,所以可按照b->data三元组表的次序在 a->data中找到相应的三元组进行转置,即可按a->data的列序转置,所得 到的转置矩阵B的三元组表b->data必定是按行优先存放的。因此,可以对 三元组表a->data从第一行起扫描,找到A的每一列中所有的非零元素,就 可以实现转置。
LOC ( aij ) =LOC ( a00) +(i×n+j) × c 同理可推导出以列为主序优先存储时数据元素a i j 的存储地址,其计算公式 为:
LOC( a i j ) =LOC( a00 ) +( j × n +i ) × c 对于三维数组Am×n×p而言,若以行为主序优先存储时,则其数据元 素aijk的存储地址可为: LOC ( a i j k) =LOC ( a000) +[ i × m×p +j ×p +k] × c 对于一般的二维数组A[c1…d1,c2…d2]而言,此处c1,c2的值不一定是 0,a i j 的地址为: LOC ( a i j ) =LOC ( a c 1 c 2 ) +[ ( i – c 1 )* ( d 2 – c 2 +1) +j – c 2 ] * c
第五章 数组与广义表

第五章数组、特殊矩阵和广义表本章介绍的数组与广义表可视为线性表的推广,其特点是数据元素仍然是一个表。
本章讨论多维数组的逻辑结构和存储结构、特殊矩阵、矩阵的压缩存储、广义表的逻辑结构和存储结构等。
5.1 多维数组5.1.1 数组的逻辑结构数组是我们很熟悉的一种数据结构,它可以看作线性表的推广。
数组作为一种数据结构其特点是结构中的元素本身可以是具有某种结构的数据,但属于同一数据类型,比如:一维数组可以看作一个线性表,二维数组可以看作“数据元素是一维数组”的一维数组,三维数组可以看作“数据元素是二维数组”的一维数组,依此类推。
图5.1是一个m行n 列的二维数组。
标识,因此,在数组上不能做插入、删除数据元素的操作。
通常在各种高级语言中数组一旦被定义,每一维的大小及上下界都不能改变。
在数组中通常做下面两种操作:(1)取值操作:给定一组下标,读其对应的数据元素。
(2)赋值操作:给定一组下标,存储或修改与其相对应的数据元素。
我们着重研究二维和三维数组,因为它们的应用是广泛的,尤其是二维数组。
5.1.2 数组的内存映象现在来讨论数组在计算机中的存储表示。
通常,数组在内存被映象为向量,即用向量作为数组的一种存储结构,这是因为内存的地址空间是一维的,数组的行列固定后,通过一个映象函数,则可根据数组元素的下标得到它的存储地址。
对于一维数组按下标顺序分配即可。
对多维数组分配时,要把它的元素映象存储在一维存储器中,一般有两种存储方式:一是以行为主序(或先行后列)的顺序存放,如BASIC、PASCAL、COBOL、C等程序设计语言中用的是以行为主的顺序分配,即一行分配完了接着分配下一行。
另一种是以列为主序(先列后行)的顺序存放,如FORTRAN语言中,用的是以列为主序的分配顺序,即一列一列地分配。
以行为主序的分配规律是:最右边的下标先变化,即最右下标从小到大,循环一遍后,右边第二个下标再变,…,从右向左,最后是左下标。
以列为主序分配的规律恰好相反:最左边的下标先变化,即最左下标从小到大,循环一遍后,左边第二个下标再变,…,从左向右,最后是右下标。
数据结构第5章数组和广义表2广义表ppt课件PPT精品文档33页

表中的第一个元素)和指示表尾的表尾指针域(指向除 去原表头元素后的广义表)。
4)D=( A , B ,C )
n=3,3个元素都是子表
5)E=(a, E)
n=2,a 为原子,E为子表
D=(A,B,C)=(( ),(e),(a,(b,c,d))),共享表
E=(a,E)=(a,(a,E))= (a,(a,(a,…….))),E为递归表
§5.4 广义表的类型定义
❖试用图形表示下列广义表
§5.4 广义表的类型定义 ❖广义表的特点
▪ 可共享
广义表的元素可以为其他广义表所共享 A = ( a , B ) =( a , ( b , c , d ) )
§5.4 广义表的类型定义
❖例1:求下列广义表的长度
1)A =( )
n=0,因为A是空表
2)B = ( e )
n=1,表中元素e是原子
3)C =( a ,( b , c , d ) ) n=2,a 为原子,(b, c, d)为子表
6. GetHead{ ( ( ) ) }= ( ) .
7. GetTail{ ( ( ) ) }= ( ) .
(a, b)
§5.4 广义表的类型定义 ❖注意:( )和( ( ) )的区别
前者为空表,长度=0,深度=1; 后者长度=1,深度=2,表头、表尾均为( )
§5.5 广义表的存储结构
❖广义表的存储结构
§5.4 广义表的类型定义
❖广义表的特点
▪ 有深度
广义表的深度定义为广义表中括弧的最大重数
如: H = (d, (e,( )))深度为3 注意:(1)空表的深度为1;
数据结构课件PPT数组和广义表

{ q=1; for (col=1;col<=T.mu;++col) for(p=1;p<=M.tu;++p) if ( M.data[p].j==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; ++q; } }
(row) (col) (value)
[0] 1 4 22
[0] 1 5 91
[1] 1 7 15
[1] 2 2 11
[2] 2 2 11
[2] 3 6 28
[3] 2 [4] 3来自6 17 4 -6[3] 4 [4] 4
1 22 3 -6
[5] 4 6 39
[5] 6 2 17
[6] 5 1 91
[6] 6 4 39
cpot[1]=1 cpot[col]=cpot[col-1]+num[col-1]
稀疏矩阵的快速转置(算法5.2)
Status FastTransposeSMatrix(TSMatrix M,TSMatrix &T) { T.mu=M.nu; T.nu=M.mu; T.tu=M.tu;
if (T.tu) { for (col=1;col<=M.nu;++col) num[col]=0; for (t=1;t<=M.tu;++t) ++num[M.data[t].j]; cpot[1]=1; for ( col=2;col<=M.nu;++col) cpot[col]=cpot[col-1]+num[col-1]; for (p=1;p<=M.Tu;++p) { col=M.data[p].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]; } }
大学数据结构课件--第5章 数组和广义表

a 32 a 33 a 34 0 0
a 43 a 44 a 45 0
a 54 a 55 a 56 a 65 a 66
5.3.2 稀疏矩阵
稀疏矩阵的存储:如何表示非零元素的位置信息 1. 三元组表:每个元素用一个三元组(i,j,v)来表示。 i j v
0 1 6 1 1 6 2 3 8 12 9
2
3 4 5 6 7 8
2
5.2 数组的顺序表示和实现
a00 a00 a10 a01 存储单元是一维结构,而数组是个多维结构 , …… …… 则用一组连续存储单元存放数组的数据元素就有 am-1,0 a0,n-1 个次序约定问题。 a01 a10
a11
……
a11
……
二维数组可有两种存储方式: am-1,1 a1,n-1
……
K=
i*n-i(i-1)/2+j-i n(n+1)/2
当 i≤j 当i>j
0 a11 ... a1n-1 ... ... ... ... 0 0 0 an-1n-1
当i ≤ j时,a[i][j]是非零元素, a[i][j]前面有i行,共有n+(n-1)+(n-2)+…(n-(i-1))
=i(n+[n-(i-1)])/2=i*n-i(i-1)/2个元素,a[i][j]前面有j列,共j-i个非零元素,
A m× n
( a10 a11 … a1,n-1 )
=
注:
( … … …… ) ( am-1,0 am-1,2 … am-1,n-1 ) ( ( ( (
① 数组中的元素都具有统一的类型; ② 数组元素的下标一般都具有固定的上界和下界,即数组一旦 被定义,它的维数和维界就不再发生改变; ③ 数组的基本操作简单:初始化、销毁、存取元素和修改元素值
第五章数组和广义表

稀疏矩阵M存在
由稀疏矩阵M复制 得到T
稀疏矩阵M与N的行 求稀疏矩阵的和Q 数和列数对应相等 =M+N
稀疏矩阵M与N的行 求稀疏矩阵的差Q 数和列数对应相等 =M-N
稀疏矩阵M的列数 求稀疏矩阵乘积Q
等于N的行数
=M*N
稀疏矩阵M存在
求稀疏矩阵M的转 置矩阵T
M.chead
M.rhead
30 05
113
145
M = 0 -1 0 0
2 000
2 2 -1
312
稀疏矩阵的十字链表存储表示:
typedef struct OLNode { int i, j ; // 非零元的行和列下标 ElemType e ; Struct OLNode *right, *down ; // 该非零元所在行表和列表的后继链域
1 当i
j
a00 a10 a11 a20 k= 0 1 2 3
… an-1, 0 … n(n-1)/2
an-1, n-1 n(n+1)/2-1
ADT SparseMatris { 数据对象:
D = { aij | i = 1, 2, …, m; j =1, 2, … , n; aij∈ElemSet,m和n分别称为矩阵的行数和列数}
第五章 数组和广义表
ADT Array { 数据对象:{ ji = 0, … , bi-1 , i = 1, 2 , … ,
n, D = { aj1j2…jn | n ( > 0 )称为数组的维数, bi是数组第i维的长度, ji是数组元素的第i维下标, aj1j2…jn∈ElemSet } 数据关系:R = { R1, R2, …, Rn }
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2.对称矩阵、三角矩阵、对角矩阵等特殊矩阵在计算机中的
压缩存储表示及地址计算公式; 3.稀疏矩阵的三元组表示及转置算法实现; 4.稀疏矩阵的十字链表表示及相加算法实现; 5.广义表存储结构表示及基本运算。
2018/10/10 2
5.1 数 组
数组和广义表可看成是一种特殊的线性表,其特殊在于, 表中的数所元素本身也是一种线性表。
5.1 .1 数组的定义
数组是大家都已经很熟悉的一种数据类型,几乎所有高级语
言程序设计中都设定了数组类型。
数组(Array)是由n(n>1)个相同类型数据元素a0,al,…ai…, an-1构成的有限序列。n是数组的长度。其中数组中的数据元素ai
是一个数据结构,即ai可以是线性表中的一个元素,本身也可以
线性表。在每个关系中,每个元素都有一个直接后继。因此, 就其单个关系而言,这n个关系中的每一个仍然是一种线性
关系。
数组中每个元素都是由一个值和一组下标来确定的。同线性 表一样,数组中的所有数据元素都必须属于同一数据类型。 元素下标的个数被称为数组的维数。显然,当维数为1时, 数组就退化为定长的线性表。
可以看成由m个行向量组成的向量,也可以看由n个列向量组成 的向量。 数组中的每个元素由元素值 aij 及一组下标( i,j)来确定。 aij既属于第i行的行向量,又属于第j列的列向量。 其中,ai=( ai,0 ai,1 … ai,n-1) (0≤i<n) 可以认为Am*n=A,A是这样的一维数组: A=( a0,al,…,ai,…,am-1)
第5章 数组和广义表
本章主题:多维数组、特殊矩阵和广义表 教学目的:掌握数组和广义表的定义、运算及存储结构 教学难点:矩阵的压缩存储
2018/10/10
1
本章学习导读
本章主要介绍数组的概念及多维数组在计算机中的存放, 特殊矩阵的压缩存储及相应运算,广义表的概念和存储结构及 其相关运算的实现。通过本章学习,要求掌握如下内容: 1.多维数组的定义及在计算机中的存储表示;
2018/10/10 7
5.1.2 数组的基本操作
数组一旦被定义,它的维数和维界就不再改变。因此,除了结 构的初始化和销毁之外,数组的基本操作一般不会含有元素的插入 或删除等操作,数组只有访问数组元素和修改元素值的操作。 (1) value(A,indexl,index2,…,indexd):A是已存在的d维 数组,indexl,index2,…,indexd是指定的d个下标值,且这些下 标均不超过对应维的上界。其运算结果是返回由下标指定的A中的 对应元素的值。 (2) assign(A,e,indexl,index2,…,indexd):A 是已存在的 d 维数组, e 为元素变量, indexl,index2,…,indexd 是指定的 d 个 下标值,且这些下标均未越界。其运算结果是将 e 的值赋给由下标 指定的A中的对应元素。
2.二维数组
二维数组,又称矩阵 (matrix)。二维数组中的每一个元素又是
一个定长的线性表(一维数组),都要受到两个关系即行关系和 列关系的约束,也就是每个元素都同属于两个线性表。例如,设A
是一个有m行n列的二维数组,则A可以表示为:
2018/10/10 5
A
m × n
=
a0,0 a0,1 … a0,n-1 a1,0 a1, … a1,n-1 1 … … … … am -1,0 am -1,1… am -1,n-1
2018/10/10 6
显然,二维数组同样满足数组的定义。一个二维数组可以看 作是每个数据元素都是相同类型的一维数组。以此类推,任何多 维数组都可以看作一个线性表,这时线性表中的每个数据元素也
是一个线性表。多维数组是特殊的线性表,是线性表的推广。
数组的性质: (1) 数组中的数据元素数目固定。一旦定义了一个数组,其数据 元素数目不再有增减变化。它属于静态分配存储空间的数据结构。 (2) 数组中的数据元素必须具有相同的数据类型。 (3) 数组中的每个数据元素都有一组唯一的下标值。 (4) 数组是一种随机存储结构。可随机存取数组中的任意数 据元素。
2018/10/10
4
1.一维数组
一维数组可以看成是一个线性表或一个向量,它在计算机内是 存放在一块连续的存储单元中,适合于随机查找。
一维数组记为A[n]或A=( a0,al,…ai,…,an-1)
一维数组中,一旦a0的存储地址、一个数据元素所占存储单元 数k确定,则ai的存储地址LOC(ai)就可求出: LOC(ai)=LOC(a0)+i*k (0≤i<n)
是一个线性表,而线性子表中的每一个数据元素还可以再分 解…… 。根据数组元素ai的组织形式不同,数组可以分为一维数 组、二维数组以及多维(n维)数组。
2018/10/10 3
有时也把一维数组称为向量,二维数组称为矩阵。在二 维或多维数组中,每个数组元素都受到2个或n个关系的约
束。当数组为n维时,其对应线性表中的每个元素又是一个
2018/10/10
9
5.1.3 数组的存储结构
由于数组一般不作删除或插入运算,所以一旦数组被定义后, 数组中的元素个数和元素之间的关系就不再变动。通常采用顺序存 储结构表示数组。 对于一维数组,数组的存储结构关系为: LOC(ai)=LOC(a0)+i * k (0≤i<n)
对于二维数组,由于计算机的存储单元是一维线性结构,如何 用线性的存储结构存放二维数组元素就有行/列次序问题。常用两 种存储方法:以行序(row major order)为主序的存储方式和以列 序(column major order)为主序的存储方式。
2018/10/10Fra bibliotek8(3) disp(A):输出数组A的所有元素。
在大多数程序设计语言中,取数组元素值操作value(A,indexl, index2,…,indexd) 通常直接写作A[indexl][ index2]…[indexd] ,而对数组元素的赋值操作assign(A,e,indexl,index2,…, indexd)写作e= A[indexl][ index2]…[indexd],或者类似的形式。