第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中列号
一、三元组顺序表
对于稀疏矩阵,非零元可以用三元组表示, 整个稀疏矩阵可以表示为所有非零元的三元组所 构成的线性表。例如:
第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。
《数据结构——用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语言中,用的是以列为主序的分配顺序,即一列一列地分配。
以行为主序的分配规律是:最右边的下标先变化,即最右下标从小到大,循环一遍后,右边第二个下标再变,…,从右向左,最后是左下标。
以列为主序分配的规律恰好相反:最左边的下标先变化,即最左下标从小到大,循环一遍后,左边第二个下标再变,…,从左向右,最后是右下标。
数组和广义表 数据结构
3.建立广义表的存储结构 假定广义表中的元素类型ElemType为chai类型,每个原子的值被限 定为英文字母。并假定广义表是一个表达式,其格式为:元素之间用一 个逗号分隔,表元素的起止符号分别为左、右圆括号,空表在其圆括号 内不包含任何字符。例如“(a,(b, c, d))”就是一个符合上述规定的广 义表格式。 建立广义表存储结构的算法同样是一个递归算法。该算法使用一个 具有广义表格式的字符串参数s,返回由它生成的广义表存储结构的头结 点指针h。在算法的执行过程中,需要从头到尾扫描s的每一个字符。当 碰到左括号时,表明它是一个表元素的开始,则应建立一个由h指向的表 结点,并用它的sublist域作为子表的表头指针进行递归调用,来建立子 表的存储结构;当碰到一个英文字母时,表明它是一个原子,则应建立 一个由h指向的原子结点;当碰到一个“)”字符时,表明它是一个空表, 则应置h为空。当建立了一个由h指向的结点后,接着碰到逗号字符时, 表明存在后继结点,需要建立当前结点(即由h指向的结点)的后继表; 当碰到右括号或分号字符时,表明当前所处理的表已结束,应该置当前 结点的link域为空。 4.输出广义表 5.广义表的复制
广义表的转换过程
为了使子表和原子两类结点既能在形式上保持一致,又能进
行区别,可采用如下结构形式:
其中,tag域为标志字段,用于区分两类结点。sublist或data
域由tag决定。若tag=0,表示该结点为原子结点,则第二个 域为data,存放相应原子元素的信息;若tag=l,表示该结点 为表结点,则第二个域为sublist,存放相应子表第一个元素 对应结点的地址。link域存放与本元素同一层的下一个元素所 在结点的地址,当本元素是所在层的最后一个元素时,link域 为NULL。 例:前面的广义表C的存储结构如下图所示(很多《数据结构 公教科书上称之为带表头结点的广义表的链表存储结构
第5章 数组和广义表
第五章数组和广义表讲课提要【主要内容】1.多维数组的顺序存储结构2.特殊矩阵的压缩存储3.广义表的定义及其与线性表的关系4.广义表的存储结构5.广义表运算实现中递归的应用【教学目标】1.掌握多维数组的顺序存储结构2.掌握特殊矩阵的压缩存储方法3.掌握广义表的定义及其与线性表的关系4.掌握广义表的存储结构5.了解广义表运算实现中递归的应用学习指导1.多维数组的顺序存储结构对于多维数组,有两种存储方式:一是以行为主序(或先行后列)的顺序存放,如BASIC、PASCAL、C等程序设计语言中用的是以行为主的顺序分配,即一行分配完了接着分配下一行。
另一种是以列为主序(先列后行)的顺序存放,如FORTRAN语言中,用的是以列为主序的分配顺序,即一列一列地分配。
以行为主序的分配规律是:最右边的下标先变化,即最右下标从小到大,循环一遍后,右边第二个下标再变,…,从右向左,最后是左下标。
以列为主序分配的规律是:最左边的下标先变化,即最左下标从小到大,循环一遍后,左边第二个下标再变,…,从左向右,最后是右下标。
不论按何种方式存储,只要确定了数组的首地址以及每个数组元素所占用的单元数,就可以将数组元素的存储地址表示为其下标的线性函数。
设有m×n二维数组A mn,以“以行为主序”的分配为例,按照元素的下标确定其地址的计算方法如下。
设数组的基址为LOC(a11),每个数组元素占据L个地址单元,计算a ij 的物理地址的函数为:LOC(a ij) = LOC(a11) + ( (i-1)*n + j-1 ) * L同理,对于三维数组A mnp,即m×n×p数组,对于数组元素a ijk其物理地址为:LOC(a ijk)=LOC(a111)+( ( i-1) *n*p+ (j-1)*p +k-1) )*L注意:在C语言中,数组中每一维的下界定义为0,则:LOC(a ij) = LOC(a00) + ( i*n + j ) * L【例4-1】二维数组A的每一个元素是由6个字符组成的串,其行下标i=0,1,…,8,列下标j=1,2,…,10。
数据结构课件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 ) ( ( ( (
① 数组中的元素都具有统一的类型; ② 数组元素的下标一般都具有固定的上界和下界,即数组一旦 被定义,它的维数和维界就不再发生改变; ③ 数组的基本操作简单:初始化、销毁、存取元素和修改元素值
数据结构第5章数组与广义表
一个稀疏矩阵里存在大量的零元素,若 以常规方法,即以二维数组来存储稀疏矩 阵时产生如下问题: 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
数组和广义表
1第5章数组和广义表主要内容: 数组的基本概念数组的顺序表示和实现 矩阵的压缩存储 广义表的基本概念 广义表的存储结构2数组和广义表概述数组与广义表是线性表的推广从数据结构来看,数组与广义表是线性结构,其特殊之处在于其元素的类型被进行了扩充,是特殊的线性结构。
数组:线性表的元素也是线性表,且元素类型相同 广义表:表的元素既可以是原子,也可以是表,且元素类型可以不同从数据类型来看,数组与广义表的数据元素类型特殊,操作特点也和线性表有很大差异数组不对元素进行插入删除 广义表多采用递归的操作数组和广义表是元素类型被扩充了的特殊线性表3§5.1 数组的定义1. 数组的定义数组:是由一组类型相同的数据元素构成的有序集合,每个数据元素称为一个数组元素。
每个元素受n(n ≥1)个线性关系的约束,或者说每个数据元素是由下标和值组成偶对的一个集合,即在数组中,对于每一个数组元素,总有一组反映其在n 个线性关系中序号的下标[i 1, i 2, ……, i n ]与之对应,这样的数组称为n 维数组。
形式定义:n_ARRAY(D,R)D—数组的元素R=(R 1, R 2, …, R n ),为数组元素间的关系 数组元素每个下标[i 1, i 2, ……, i n ]的取值范围为0≤j i ≤b i -1(i =1,2,...,n )4例如:二维数组2_Array =(D,R )D={ a ij |i =0...m -1, j =0...n -1 } R={Row,Col}Row ={ <a i,j ,a i,j+1>| 0≤i ≤m -1,0≤j ≤n -2 } Col ={ <a i,j ,a i+1,j > | 0≤i ≤m -2,0≤j ≤n -1 }每个数组元素属于同一数据类型,由下标(i,j )唯一确定其位置每一个数组元素a i,j 都受两个关系Row 和Col 的约束Row(行关系):a i,j+1是a ij 在行关系中的直接后继Col(列关系):a i+1,j 是a ij 在列关系中的后继元素每个下标i,j 有其限定其范围m -1和n -15N 维数组的抽象类型定义ADT Array{数据对象: D 数据关系: R 基本操作:InitArray(Array &A, int n, int bound[ ]);//bound[ ]= b 1, b 2, ……, b nDestroyArray (Array &A);Value(Array A, ElemType &e, int index[ ]);// index[ ]= i 1, i 2, ……, i nAssign(Array &A, ElemType e, int index[ ]);}ADT Array6数组-线性表的推广数学上:把数组看成向量,多维数组是向量的推广0001020,11011121,11,01,11,21,1n n m n m m m m n a a a a a a a a A a a a a −−×−−−−−⎡⎤⎢⎥⎢⎥=⎢⎥⎢⎥⎣⎦00010,110111,111,01,11,1n n n m m m n a a a a a a A a a a −−×−−−−⎡⎤⎡⎤⎡⎤⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥=⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦⎣⎦⎣⎦⎣⎦0001020,11011121,111,01,11,21,1[][][]n n m m m m m n a a a a a a a a A a a a a −−×−−−−−⎡⎤⎢⎥⎢⎥=⎢⎥⎢⎥⎣⎦例如:二维数组A 可看成m 行向量组成的向量,也可看成n 个列向量组成的向量。
第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]
数据结构第五章 数组和广义表
5.3.1
特殊矩阵
1、对称矩阵 在一个n阶方阵A中,若元素满足下述性质: aij = aji 1≤i,j≤n 则称A为对称矩阵。 a11 1 5 1 3 7 a21 a 22 5 0 8 0 0 a31 a32 a33 1 8 9 2 6 ……………….. 3 0 2 5 1 an 1 a n 2 a n 3 …a n n 7 0 6 1 3
第5章
数组和广义表
5.1 数组的定义
5.2 数组的顺序表示和实现
5.3 矩阵的压缩存储
5.3.1 特殊矩阵
5.3.2 稀疏矩阵
5.4 广义表的定义
5.1 数组的定义
数组-----线性表的扩展 A =(a0,a1,a2,…,an-1)
a00 a10 ┇ Am×n= ai0 ┇ am-1,0 a01 … a0j … a11 … a1j … ┇ ai2 … aij … ┇ am-1,2 … am-1,j … a0,n-1 a1,n-1 ai,n-1 am-1,n-1 α0 α1 ┇ Am×n= α i ┇ α m-1
Assign( &A, e, index1, ..., indexn) 赋值操作 初始条件:A是n维数组,e为元素变量,随后是n个下标值。 操作结果:若下标不超界,则将e的值赋给所指定的A的元 素,并返回OK。 对于数组来说一旦维数确定了,每个元素的下标确定了, 那么整个数组就确定了,这样的一个数组结构除了能改变 某元素的值,其他的不能再改变。
5.2 数组的顺序表示和实现
数组类型特点: 1) 只有引用型操作,没有加工型操作; 2) 数组是多维的结构,而存储空间是一个一维的结构。 有两种顺序映象的方式。
有两种顺序映像方法: 1)以行序为主序(行优先,先行后列):先存储行号较小 的元素,行号相同者先存储列号较小的元素;
数据结构讲义第5章-数组和广义表
5.4 广义表
5)若广义表不空,则可分成表头和表尾,反之,一对表头和表尾 可唯一确定广义表 对非空广义表:称第一个元素为L的表头,其余元素组成的表称 为LS的表尾; B = (a,(b,c,d)) 表头:a 表尾 ((b,c,d)) 即 HEAD(B)=a, C = (e) D = (A,B,C,f ) 表头:e 表尾 ( ) TAIL(B)=((b,c,d)),
5.4 广义表
4)下面是一些广义表的例子; A = ( ) 空表,表长为0; B = (a,(b,c,d)) B的表长为2,两个元素分别为 a 和子表(b,c,d); C = (e) C中只有一个元素e,表长为1; D = (A,B,C,f ) D 的表长为4,它的前三个元素 A B C 广义表, 4 A,B,C , 第四个是单元素; E=( a ,E ) 递归表.
以二维数组为例:二维数组中的每个元素都受两个线性关 系的约束即行关系和列关系,在每个关系中,每个元素aij 都有且仅有一个直接前趋,都有且仅有一个直接后继. 在行关系中 aij直接前趋是 aij直接后继是 在列关系中 aij直接前趋是 aij直接后继是
a00 a01 a10 a11
a0 n-1 a1 n-1
a11 a21 ┇ a12 a22 ┇ ai2 ┇ … amj … amn … aij … ain … … a1j a2j … … a1n a2n β1 β2 ┇ βi ┇ βm
第五章数组广义表
(1)A=( )
(4)D=(A,B,C)
(2)B=(e)
(5)E=(a,E)
(3)C=(a,(b,c,d))
广义表的长度指广义表中元素的个数。
广义表的深度指广义表中括弧的重数。
从上述定义和例子可推出三个重要结论:
(1)列表的元素可以是子表,而子表的元素还可 以是子表,…。
(2)列表可以为其它列表所共享。 (3)列表可以是一个递归的表。 一、广义表的存储结构 由于广义表(a1,a2,a3,…,an)中的元素可以具有 不同的结构,因此难以用顺序存储结构表示。通 常采用链式存储结构,每个数据元素可用一个结 点表示。
else { *elem= A.elem[index1][index2];
return OK; } }
5.3矩阵的压缩存储
矩阵是在很多科学与工程计算中遇到的数学模型。 在数学上,矩阵是这样定义的:它是一个由s×n个元
素排成的s行(横向)n列(纵向)的表。下面就是一
个矩阵:
a11 a12 a 21 a 22 ... ... am1 am 2
第五章 数组和广义表
本章主要介绍下列内容 数组的定义 数组的顺序表示和实现 矩阵的压缩存储 稀疏矩阵 广义表
5.1 数组的定义
一、数组的定义和基本运算 数组的特点是每个数据元素可以又是一个线性表 结构。因此,数组结构可以简单地定义为:若线性表 中的数据元素为非结构的简单元素,则称为一维数组, 即为向量;若一维数组中的数据元素又是一维数组结 构,则称为二维数组;依次类推,若二维数组中的元 素又是一个一维数组结构,则称作三维数组。 结论:线性表结构是数组结构的一个特例,而数 组结构又是线性表结构的扩展。举例:
... a1n ... a 2 n ... ... ... amn 图5-2 Nhomakorabea×n的矩阵
第5章 数组和广义表
稀疏矩阵压缩存储结构
三元组的顺序表 行逻辑链接的顺序表 十字链表
三元组的顺序表表示
#define MAXSIZE 12500 //假设非零元个数的最大值 Typedef struct { int i, j; //该非零元的行下标和列下标 ElemType e; }Triple; Typedef struct { Triple data[MAXSIZE+1]; //非零元三元组表,data[0]未用 int mu ,nu ,tu; //矩阵的行数,列数和非零元个数 }TSMatrix;
Sa[k]
a11 a21 a22 a31 a32 a33 a41 a42 aij an(n-1) ann
n(n+1)/2-1
i(i-1) +j-1 2 k= j(j-1) 2 +i-1
i≥j
j≥i
ann
0
1
2
3
4
5
6
7
?
特殊矩阵
三角矩阵
定义:矩阵的下(上)三角(不包括对角线)中的元均为常数c或 定义 零的n阶矩阵
M由{(1,2,12), (1,3,9), (3,1,-3), (3,6,14), (4,3,24), (5,2,18), (6,1,15), (6,4,-7) } 和矩阵维数(6,7)唯一确定
稀疏矩阵可由表示非零元的三元组 及其行列数唯一确定。 行列数唯一确定 稀疏矩阵可由表示非零元的三元组 及其行列数唯一确定。
二维数组类型定义: Typedef ElemType Array2[m][n]; 等价于 Typedef ElemType Array1[n]; Typedef Array1 Array2[m]; ① 二维数组类型可以定义为其分量类型为一维数组 的一维数组类型 ② 在二维数组中,每一个元素具有两个约束关系 ③ 一个n维数组类型可以定义为其数据元素为n-1维 数组类型的一维数组类型 ④ 在n维数组中,每一个元素具有n个约束关系
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
5.1 数组的定义
数组——线性表的推广
a11 a12 … a1n
A=
a21 a22 … a2n … … ……
am1 am2 … amn
A=(A1,A2,……,An)
其中: Ai=(a1i,a2i,……,ami)
(1≤i≤n)
二维数组是数据元素为线性表的线性表。
5.1 数组的定义
数组的基本操作
在数组中插入(或删除)一个元素有意义吗?
5.1 数组的定义
数组的定义
数组是由一组类型相同的数据元素构成的有序集 合,每个数据元素称为一个数组元素(简称为元 素),每个元素受n(n≥1)个线性关系的约束,每 个元素在n个线性关系中的序号i1、i2、…、in称为 该元素的下标,并称该数组为 n 维数组。
数组的特点
➢元素本身可以具有某种结构,属于同一数据类型;
⑴ 存取:给定一组下标,读出对应的数组元素; ⑵ 修改:给定一组下标,存储或修改与其相对应的 数组元素。
存取和修改操作本质上只对应一种操作——寻址
数组应该采用何种方式存储?
数组没有插入和删除操作,所以,不用预留空间, 适合采用顺序存储。
5.1 数组的定义
ADT Array {
数据对象:
D={aj1,j2, ...,,jn| ji =0,...,bi -1, i=1,2,..,n } 数据关系:
L
二维数组A中任一元素ai,j 的存储位置 LOC(i,j) = LOC(0,0) + (b2×i+j)× L
称为基地址或基址。
以“列序为主序”的存储映象 例如:
a0,0 a0,1 a0,2 a1,0 a1,1 a1,2
操作结果:若各下标不超界,则e赋值为 所指定的A 的元素值,并返 回OK。
Assign(&A, e, index1, ..., indexn)
初始条件:A是n维数组,e为元素变量, 随后是n 个下标值。
操作结果:若下标不超界,则将e的值赋 给所指定的A的元素,并返回 OK。
5.2 数组的顺序表示和实现
➢数组是一个具有固定格式和数量的数据集合。
程序设计关注数组的使用,而数据结构关注数组的内部实现。
数组示例
5.1 数组的定义
a11 a12 … a1n
A=
a21 a22 … a2n … … ……
am1 am2 … amn
例如,元素a22受两个线性关系的约束,在行上有
一个行前驱a21和一个行后继a23,在列上有一个列 前驱a12和和一个列后继a32。
R={R1, R2, ..., Rn} Ri={<aj1,... ji,... jn , aj1, ...ji +1, ...jn > | 0 jk bk -1, 1 k n 且k i, 0 ji bi -2, i=2,...,n } 基本操作:
} ADT Array
二维数组的定义:
InitArray(&A, n, bound1, ..., boundn)
操作结果:若维数 n 和各维长度合法, 则构造相应的数组A,并 返回OK。
DestroyArray(&A) 操作结果:销毁数组A。
Value(A, &e, index1, ..., indexn)
初始条件:A是n维数组,e为元素变量, 随后是n 个下标值。
数组的存储结构与寻址——一维数组
设一维数组的下标的范围为闭区间[l,h],每个 数组元素占用 L个存储单元,则其任一元素 ai 的存 储地址可由下式确定:
Loc(ai)=Loc(al)+(i-l)×L
c
al al+1 … … ai-1 ai … … ah
Loc(al)
Loc(ai)
5.2 数组的顺序表示和实现
B2-1
整 行
0
数
aij
b1-1
(a) 二维数组
本行中aij前面的元素个数
aij前面的元素个数
=阴影部分的面积 =整行数×每行元素个数+本行中
aij前面的元素个数
=i ×b2+j
以“行序为主序”的存储映象 例如:
a0,0 a0,1 a0,2 a1,0 a1,1 a1,2
a0,0 a0,1 a0,2 a1,0 a1,1 a1,2
将元素 x 插入 到数组中第1行第2列。
x
a11 a12 … a1n
A=
a21 a22 … a2n … … ……
A=
am1 am2 … amn
删除数组中 第1行第2列元素。
a11 a12 … a1n a21 a22 … a2n … … …… am1 am2 … amn
5.1 数组的定义
数组的基本操作
数据对象: D = {aij | 0≤i≤b1-1, 0 ≤j≤b2-1}
数据关系:
R = { ROW, COL }
ROW = {<ai,j,ai+1,j>| 0≤i≤b1-2, 0≤j≤b2-1} COL = {<ai,j,ai,j+1>| 0≤i≤b1-1, 0≤ j≤b2-2}
基本操作:
InitArray(&A, n, bound1, ..., boundn) DestroyArray(&A) Value(A, &e, index1, ..., indexn) Assign(&A, e, index1, ..., indexn)
第五章 数组和广义表
线性表——具有相同类型的数据元素的有限序列。 将元素的类型进行扩充
广 (多维)数组——线性表中的数据元素可以是 义 线性表,但所有元素的类型相同。 线 性 广义表——线性表中的数据元素可以是线性表, 表 且元素的类型可以不相同。
5.1 数组的定义 5.2 数组的顺序表示和实现 5.3 矩阵的压缩存储 5.4 广义表的类型定义 5.5 广义表的表示方法
第五章 数组和广义表
第五章 数组和广义表
线性表——具有相同类型的数据元素的有限序列。 限制插入、删除位置
特 栈——仅在 性
队列——在一端进行插入操作,而另一端进行 删除操作的线性表。
表 串——零个或多个字符组成的有限序列 。
限制元素类型为字符
线性表——具有相同类型的数据元素的有限序列。
数组的存储结构与寻址——二维数组
二维数组
内存
二维结构
一维结构
常用的映射方法有两种:
➢按行优先:先行后列,先存储行号较小的元素, 行号相同者先存储列号较小的元素。
➢按列优先:先列后行,先存储列号较小的元素, 列号相同者先存储行号较小的元素。
5.2 数组的顺序表示和实现
按行优先存储的寻址
每行元素个数
0