第五章 数组和广义表
数据结构第五章 数组与广义表
压缩存储方法:只需要存储下三角 (含对角线)上的元素。可节省一 半空间。
可以使用一维数组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中列号
一、三元组顺序表
对于稀疏矩阵,非零元可以用三元组表示, 整个稀疏矩阵可以表示为所有非零元的三元组所 构成的线性表。例如:
第五章数组和广义表
i(i-1)/2+j-1 (i≥j) k= 第五章数j组(j和-1广)义/2表+i-1 (i<j)
第五章数组和广义表
5.1 数组的类型定义 5.2 数组的顺序存储和实现 5.3 特殊矩阵的压缩存储 5.4 广义表
第五章数组和广义表
5.1 数组的定义和运算
数组是一种数据类型。从逻辑结构上看,数 组可以看成是一般线性表的扩充。二维数组可 以看成是线性表的线性表。例如:
Am×n=
a11 a12 … a1j ……
LO(0C ,0,..0.) , ci ji (Cn=L,ci-1=bi*ci,1<i≤n) i1
数组元素的存储位置是其下标的线性函数,由于计算各 个元素存储位置的时间相等,所以存储数组中任一元素的 时间也相等,称具有这一第五特章数点组和的广义存表 储结构为随机存储结构。
N维数组数据元素存储地址计算
i= (ai1,ai2, …,aij ,…,ain)。
B
‖
a11 a12 … a1j … a1n
1
……
…
Am×n= ai1 ai2 … aij … ain
i
……
…
am1 am2 … amj … amn
m
第五章数组和广义表
看一个二维数组的简单情况。
D={aij|0≤i≤b1-1,0≤j≤b2-1, aij∈ ElemType}
}
第五章数组和广义表
5.3 矩阵的压缩存储
• 压缩存储:为多个值相同的元素只分配一个存 储空间,对零元素不分配空间。
• 目的:节省存储空间 • 任务:压缩存储矩阵并使矩阵的运算有效进行。 • 矩阵的存储:二维数组 • 可压缩存储的矩阵有两类:
数据结构-第五章 数组与广义表-文档资料
上 三 角 矩 阵 下 三 角 矩 阵
a00 a10 a 20 an10
0 1 2
a01 a11 a21 an11
3 4
a02 a12 a22 an12
5
6 7
a0 n1 a1n1 a2 n1 an1n1
行 列 值 (row) (col) (value) 0 4 91 1 1 11 2 5 28 3 0 22 3 2 -6 5 1 17 5 3 39 6 0 16
用三元组表表示的稀疏矩阵及其转置
行 列 值 (row) (col) (value) 0 3 22 0 6 15 1 1 11 1 5 17 2 3 -6 3 5 39 4 0 91 5 2 28 行 列 值 (row) (col) (value) 0 4 91 1 1 11 2 5 28 3 0 22 3 2 -6 5 1 17 5 3 39 6 0 16
4 5 6 7 8 9 10
B a00 a01 a10 a11 a12 a21 a22 a23 … an-1n-2 an-1n-1
三对角矩阵中除主对角线及在主对角线上 下最临 近的两条对角线上的元素外,所有其它元素均为 0。总共有3n-2个非零元素。 将三对角矩阵A中三条对角线上的元素按行存放在 一维数组 B 中,且a00存放于B[0]。 在三条对角线上的元素aij 满足 0 i n-1, i-1 j i+1 在一维数组 B 中 A[i][j] 在第 i 行,它前面有 3*i-1 个非零元素, 在本行中第 j 列前面有 j-i+1 个,所 以元素 A[i][j] 在 B 中位置为 k = 2*i + j。
三对角矩阵的压缩存储
数据结构第五章数组和广义表
typedef elemtype Array1[n]; typedef Array1 Array2[m]; 同理,可以用 n-1 维数组的数据类型来定义 n 维数组。
8
第8页
5.2 数组的顺序存贮结构
一、数组的顺序表示和实现
(1) 类型特点 ① 只有引用型操作,一般不作插入或删除操作; ② 数组是多维的结构,而存储空间是一个一维的结构。
第 17 页
(2) 压缩存储的有关概念 ① 压缩存储:为多个值相同的元素分配一个存储空间,对零 元不分配空间。 ② 特殊矩阵:值相同的元素或零元素在矩阵中的分布有一定 规律。 ③ 稀疏矩阵:值相同的元素或者零元素在矩阵中的分布无规 律。
第 18 页
(3) 特殊矩阵
① 概念:若n阶矩阵 A 中的元满足:aij=aji 1≤i,j≤n,则 称为n 阶对称矩阵。
第1页
第五章 数组和广义表
5. 1 数组的定义 5.2 数组的顺序存储结构 5. 3 矩阵的压缩存储 5. 4 广义表的定义 5.5 广义表的存储结构
第2页
第五章 数组和广义表
前4章介绍的数据结构共同特点: ▲ 都属于线性数据结构; ▲ 每种数据结构中的数据元素,都作为原子数据, 不再进行分解; 本章讨论的两种数据结构:数组和广义表,其共 同特点是: ▲ 从逻辑结构上看它们,可看成是线性结构的一 种扩展; ▲ 数据元素本身也是一个数据结构;
4
第4页
(2) 二维数组的解释
二维数组中的每个元素都受两个 线性关系的约束,即行关系和列关系, 在每个关系中,每个元素aij都有且仅 有一个直接前趋,都有且仅有一个直 接后继。
aa … 00 01
《数据结构——用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章 数组和广义表[28页]
1 4 91
( 2 3 10 )
2 3 10
(2 5 3 )
B= 2 5 3
( 3 6 28 )
3 6 28
( 4 2 22 )
4 2 22
(4 4 9 )
44 9
( 6 1 -15)
6 1 -15
把该三元组表表示成一个三列二维数组B,为使三列二维数组B
与所表示的矩阵N建立起唯一的对应关系,还需要表示出矩阵
i (i-1)/2 + j i≥ j
k=
j ( j-1)/2+ i i < j
此时矩阵A中各元素值可由下式得到:
aij= B(k)
2.5 数组与矩阵的表示
3. 对角矩阵 对角矩阵——非0元素分布在主对角线及对称两侧
如,n 阶的五对角矩阵A: 若用一维数组B以行为主存放A中的非0元素, 当2≤i<n 时,A中非0元素aij的下标i、j与元 素在 B 中的下标 k 之间的对应关系为: k = 5(i-1) – 3 + [j-(i-3)] = 4i + j-5 矩阵A中各元素值可由下式得到:
2 = ( a21 a22 … …a2n ) ﹕
a11
﹕
a12
…
m= ( am1 am2… …amn )
即 A=(1, 2… … m ) 构成线性表 , 按顺序存放行向量及其中的元素,则有:
a1n a21
根据存储关系,容易计算出aij的地址:
a22
…
ADR(aij)=ADR(a11)+[(i-1)*n+j-1]*l
N的行、列数和非0元素个数,称之为三元组顺序表
2.5 数组与矩阵的表示
用三元组表B表示后,访问矩阵元素Nij的方法有: (1) 根据i, j值从B的第0行开始查找 ( 先查找 i, 再查找 j ):
数组和广义表 数据结构
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。
第5章数组和广义表
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个元素组 成。由于这个性质,使得对数组的操作不像对线性表的操作 那样可以在表中任意一个合法的位置插入或删除一个元素。 对于数组的操作一般只有两类:
第五章数组和广义表
稀疏矩阵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 }
第5章 数组和广义表09
特殊矩阵
包括对称矩阵、三角矩阵等。
第5章 数组和广义表
11
对称矩阵
对称矩阵中,aij=aji,其中1≤i≤n,1≤j≤n, 对称矩阵关于主对角线对称,因此只需要存储 上三角或者下三角部分即可。 若只存储下三角部分,其中aij(j≤i且1 ≤ i ≤ n)与上三角中的aji相等。原来需要n×n个存储 单元,现在需要n×(n+1)/2个存储单元,可以 节省n(n-1)/2个单元。
第5章 数组和广义表
25
十字链表
按行的单链表表示的稀疏矩阵,每个节点可以容易地找 到行的后继节点,但很难找到列的后继节点。为充分表 示行和列的后继节点,可以使用十字链表。 十字链表:将行的单链表和列的单链表结合起来存储稀 疏矩阵。 每个节点表示一个非零元素,由5个成员变量组成:行 下标,列下标,值,行后继节点指针以及列后继节点指 针。 另外需要一个行指针数组存放行的单链表的头指针;一 个列指针数组存放列的单链表的头指针。 各行和各列的非零元素都分别链接在一起,查找数据可 以在行的单链表中进行,也可以在列的单链表中进行。 特点:结构灵活,使用方便。
第5章 数组和广义表
26
⎡1 ⎢0 ⎢ A = ⎢2 ⎢ ⎢0 ⎢8 ⎣
0 0 0 0 0
0 0 7 0 0
0⎤ 0⎥ ⎥ 0 1⎥ ⎥ 0 5⎥ 0 7⎥ ⎦ 0 0
第5章 数组和广义表
27
struct OLNode { int i,j;//行列标 int e;//值 OLNode *right,*down;//行后继指针 }; typedef OLNode *OLink; struct CrossList { int mu,nu,tu;//行数、列数和非零元素个数 OLink *rhead,*chead;//行、列头指针数组 };
数据结构第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
第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]
数据结构 第五章 数组和广义表
则行优先存储时的地址公式为: LOC(aij)=LOC(ac1,c2)+[(i-c1)*(d2-c2+1)+j-c2)]*L
数组基址
aij之前的行
数
总列数,即 第2维长度
aij本行前面
的元素个数
单个元素 长度
例2一个二维数组A,行下标的范围是1到6,列下标的范围是0
到7,每个数组元素用相邻的6个字节存储,存储器按字节编址。 288 个字节。 那么,这个数组的体积是
2.若对n阶对称矩阵A以行序为主序方式将其下三 角形的元素(包括主对角线上所有元素)依次存 放于一维数组B[1..(n(n+1))/2]中,则在B 中确定aij(i<j)的位置k的关系为( )。 A. i*(i-1)/2+j B. j*(j-1)/2+i C. i*(i+1)/2+j D. j*(j+1)/2+i
维界虽未变,但此时的a[32,58]不 再是原来的a[32,58]
例5:假设有三维数组A7×9×8,每个元素用相邻的6个字节存
储,存储器按字节编址。已知A的起始存储位置(基地址)为 1000,末尾元素A[6][8][7]的第一个字节地址为多少?若按 高地址优先存储时,元素A[4][7][6]的第一个字节地址为多 少? 答: 末尾元素A[6][8][7]的第1个字节地址= 1000 +(9*8*6+8*8+7)*6=4018 提示:将第1维看作“页码”,后面两维就是每页上的二维数组 。 计算地址 的意义: 只要计算出任一数组元素的地址,就 能对其轻松地进行读写操作!
4.已知数组A[0..9,0..9]的每个元素占5个存储 单元,将其按行优先次序存储在起始地址为 1000的连续的内存单元中,则元素A[6,8]的 地址为_________
数据结构讲义第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的矩阵
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第五章数组和广义表一.选择题1.在二维数组A 中引用A[i,j]的时间_________。
A.与i、j的大小有关B.与i、j的大小无关C.与i的大小有关,与j的大小无关D.与i的大小无关,与j的大小有关2.在稀疏矩阵的带行指针向量的链接存储中,每一行单链表中的结点都具有相同的________。
A.行号 B.列号 C.元素值 D.地址3.二维数组A 按行顺序存储,其中每个元素占1个存储单元。
若 A[1][1]的存储地址为420, A[3][3]的存储地址为446,则A[5][5]的存储地址为_______。
A.470 B.471 C.472 D. 4734.在稀疏矩阵的十字链接存储中,每个列单链表中的结点都具有相同的_____。
A.行号 B.列号 C.元素值 D.地址5.下面的说法中,不正确的是________。
A.对称矩阵中只须存放包括主对角线元素在内的下(或上)三角部分的元素即可B.对角矩阵中只须存放的非零元素即可C.稀疏矩阵中值为零的元素较多,因此可以采用三元组表方法存储D.稀疏矩阵中大量值为零的元素分布有规律,因此可以采用三元组表方法存储6.对一些特殊矩阵采用压缩存储的目的主要是为了________。
A.表达变得简单 B.对矩阵元素的存取变得简单C.去掉矩阵中的多余元素 D.减少不必要的存储空间的开销7.若将n 阶对称矩阵 A 按照行序为主序方式将包括主对角线元素在内的下三角形的所有元素依次存放在一个一维数组 B 中,则该对称矩阵在 B 中占用了________个数组元素。
A.n2 B.n*(n-1) C.n*(n+1)/2 D.n*(n-1)8. 稀疏矩阵的三元组顺序表表示的一个三元组中不包括________。
A. 行号B.列号C.元素值D.元素总数9.稀疏矩阵一般的压缩存储方法有两种,即________。
A.二维数组和三维数组 B.三元组和散列C. 三元组和十字链表 D.散列和十字链表10.有一个 10 阶对称矩阵 A,采用压缩存储方式(以行序为主存储,且A[0 Ⅱ0]=1),则A[8][5]的地址是________。
A.52 B.48 C.54 D.5311.数组通常具有的两种基本操作是________。
A.建立与删除 B.索引和修改 C.查找和修改 D.查找与索引12.二维数组M 的成员是 6 个字符(每个字符占一个存储单元)组成的串,行下标 i 的范围从0 到 8,列下标j 的范围从1到10,则存放M 至少需要________个字节。
A.90 B.180 C.240 D.54013.二维数组M 的元素是4 个字符(每个字符占一个存储单元)组成的串,行下标 i 的范围从0 到 4 ,列下标j 的范围从0 到 5,M 按行存储时元素M[3 Ⅱ5]的起始地址与M 按列存储时元素________的起始地址相同。
A.M[2][4] B.M[3][4] C.M[3][5] D.M[4][4]14.下面的说法中,不正确的是________。
A.数组是一种线性表结构B.数组是一种定长的线性表结构,C.除了插入与删除操作外,数组的基本操作还有存取、修改、检索和排序等D.数组的基本操作有存取、修改、检索和排序等,没有插入与删除操作15.数组的逻辑结构不同于下列________的逻辑结构。
A.线性表 B.栈 C.队列 D.树16.设有一个10阶的下三角矩阵A(包括对角线),按照从上到下、从左到右的顺序存储到连续的55个存储单元中,每个数组元素占1个字节的存储空间,则A[5][4]地址与A[0][0]的地址之差为________。
A.10 B.19 C.28 D.5517.将10阶对称矩阵压缩存储到一维数组A中,则数组 A的长度最少为________。
A.100 B.40 C.55 D.8018.设矩阵A是一个对称矩阵,为了节省存储空间,将其下三角部分按行序放在一维数组B[1,n(n+1)/2]中。
下三角部分中任一元素 Aij(i>=j),在一维数组 B 中的下标位置是 ________。
A.i(i-1)/2+j-1 B.i(i-1)/2+jC.i(i+1)/2+j-1 D. i(i+1)/2+j19.三维数组A[4][5][6]按行优先存储方法存储在内存中,若每个元素占2个存储单元,且数组中第一个元素的存储地址为120,则元素A[3][4][5]的存储地址为________。
A.356 B.358 C.360 D.36220.二维数组 Amn 按行序为主序存放在内 ,每个数组元素占 1 个存储单元 ,则元素Aij的地址计算公式是:________。
A.loc(Aij )=loc(A11)+[(i-1)*m+(j-1)]B.loc(Aij )=loc(A11)+[(j-1)*m+(i-1)]C.loc(Aij )=loc(A11)+[(i-1)*n+(j-1)]D. loc(Aij )=loc(A11)+[(j-1)*n+(i-1)]21.广义表(a,b,c,d)的表头是________。
.A.a B.(a) C.a,b,c D. (a,b,c)22.若广义表K满足head(K)=tail(K),则K为 ________。
A.( )B.( ( ) )C.(()),(())D. ((),(),())23.设一个广义表中结点的个数为n,则广义表深度算法的时间复杂度为________ 。
A.O(1)B.O(n)C. O(n2)D. O(log2n)24.下列广义表中,深度为 2的有________。
A.(a,b)B.((c,(a,b)),d)C.(c,(a,b))D.((a,b),(c,(a,b)))25.广义表 A=(a,b,(c,d),(e,(f,g))),则Head(Tail(Head(Tail(Tail(A )))))的值为________。
A. (g)B.(d)C.cD. d二.填空题1. 设有一个n 阶的下三角矩阵A,如果按照行的顺序将下三角矩阵中的元素(包括对角线上元素)存放在n(n+1)/2个连续的存储单元中,则A[i][j]与A[0][0]之间有_______个数据元素。
2.数组A 中,每个元素A 的长度为3 个字节,行下标i 从1 到8,列下标j 从1 到10,从首地址100 开始连续存放在存储器内,该数组若按行主序存放时,元素A[8][5]的起始地址为 ________;该数组若按列主序存放时,元素A[8][5]的起始地址为__________ 。
3. 假设有二维数组A[6][8],每个元素用相邻的6 个字节存储,存储器按字节编址。
已知A 的起始存储位置(基地址)为1000,则数组A 的体积(存储量)为________ ;末尾元素A57的第一个字节地址为________;若按行存储时,元素A14的第一个字节地址为_________ ;若按列存储时,元素A47的第一个字节地址为__________ 。
4. 若一个n 阶矩阵A 中的元素满足:Aij =Aji(0<=i ,j<=n-1)则称A 为________矩阵;若主对角线上方(或下方)的所有元素均为零时,称该矩阵为__________。
5. 已知广义表A=((a,b,c),(d,e,f)),则运算head(head (tail(A)))=________。
6. 一个广义表中的元素分为________元素和________元素两类。
7. 稀疏矩阵中第2 行3 列的元素值是5,它的三元组是 ________。
8. 在稀疏矩阵所对应的三元组线性表中,每个三元组元素按_________为主序、_________为辅序的次序排列。
9. 广义表A= (a,(a,b),((a,b),c)),则它的深度为____________,它的长度为____________。
10.设一个广义表中结点的个数为n,则求广义表深度算法的时间复杂度为____________。
11.设一个具有t个非零元素的m*n 大小的稀疏矩阵采用顺序存储,求其转置矩阵的普通转置算法的时间复杂度为___________ 。
12.二维数组在内存中存储可以有两种存储方式,一种是_____优先存储,一种是________优先存储。
13.设广义表L=((),(),(()))。
则head(L)是________;tail(L)是________;L的长度是________;L的深度是________。
14.设广义表L=((a),(b),((c)))则head(L)是______;tail(L)是___。
三.判断题1.在C语言中,多维数组的存储采取的是行优先的方式。
()2.广义表在本质上也是线性表。
()3.可以用三元组存储法来压缩存储稀疏矩阵。
()4.已知广义表A=((a,b,c),(d,e,f)),从A中取出原子e的运算是head(tail(head(tail(A))))。
()5. 二维数组和多维数组均不是特殊的线性结构。
()6. 数组是一种复杂的数据结构,数组元素之间的关系既不是线性的也不是树形的。
()7. 多维数组元素之间的关系是线性的。
()8. 数组可以看作是二元组<下标,值>的一个集合。
()9. 稀疏矩阵的压缩存储可以用一个三元组表来表示稀疏矩阵中的非0 元素。
()10. 一个广义表的表尾总是一个广义表。
()四.简答题1.什么叫二维数组的行序优先存储?什么叫二维数组的列序优先存储?2.什么样的矩阵叫特殊矩阵?特殊矩阵压缩存储的基本思想是什么?3.什么样的矩阵叫稀疏矩阵?稀疏矩阵压缩存储的基本思想是什么?4.已知稀疏矩阵如下:请写出该稀疏矩阵三元组表示。
5.请写出下面链表表示的广义表。
6.画出广义表list=(5,(3,2,(14,9,3),( ),4),2,(6,3,10))的链表表示。
五.程序设计题1.设计一个算法求广义表的深度。
是第i行中的最小值,同时又是第j列中的2.若矩阵A[m][n]中的某个元素aij最大值,则称此元素为该矩阵中的一个鞍点。
假设以二维数组存储矩阵,试编写算法求出矩阵中的所有鞍点。
3.对于二维数组A[m][n],其中m<=50,n<=50,先读入m和n ,然后读该数组的全部元素,对如下三种情况分别编写相应函数:(1)求数组A靠边元素之和;(2)求从A[0][0]开始的互不相邻的各元素之和;(3)当m==n时,分别求两条对角线上的元素之和,否则打印出m!=n的信息。