第五章 数组和广义表
数据结构第五章 数组与广义表
压缩存储方法:只需要存储下三角 (含对角线)上的元素。可节省一 半空间。
可以使用一维数组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 矩阵的压缩存储
• 压缩存储:为多个值相同的元素只分配一个存 储空间,对零元素不分配空间。
• 目的:节省存储空间 • 任务:压缩存储矩阵并使矩阵的运算有效进行。 • 矩阵的存储:二维数组 • 可压缩存储的矩阵有两类:
数据结构第5章数组和广义表数组ppt课件
if (!A.base) return ERROR;
数组基址指针
free(A.base); A.base = NULL; if !(A.bounds) return ERROR;
free(A.bounds); A.bounds=NULL;
各维长度保 存区指针 映保像存函区数指针ci
if !(A.constants) return ERROR; free(A.constants); A.constants=NULL; }
…
………………….
a2n
…
am1 am2 …….. amn
am1
am2
…
amn
§5.2 数组的顺序表示和实现
❖按列优先顺序存放
a11 a21
…
a11 a12 …….. a1n
am1 a12
a21 a22 …….. a2n
a22
…
………………….
am2
am1 am2 …….. amn
… a1n
a2n
一个n维数组可以看成是由若干个n-1维数组组成 的线性表。
§5.1 数组的定义
❖数组的抽象数据类型定义
ADT Array { 数据对象:D={aj1j2…jn | ji=0,…,bi-1, i=1,2,…,n,n(>0)称为数组
的维数,bi是数组第i维的长度,ji是数组元素的第i维下标, aj1…jn∈ElemSet } 数据关系: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, aj1…ji…jn , aj1…ji+1…jn∈D, i=1,2,…,n 基本操作:
第5章数组广义表
am-1,n-1
Loc(aij) = b+( aij前元素个数)•L= b+[i×n+j]×L( 存储器)
例5-1 设二维数组A[7][8],起始地址b=1000,每个元素所占单元量L=3, 则Loc(a5,6)=1000+(5•8+6)3 = 1138。
数组元素的地址计算
3.三维数组: aijk ai00 aij0
数组元素的地址计算
4.n 维数组 从以上的地址公式推导中得出这样一条规律: 任意维数组中任一元素的地址= 起址b+ 该元素前的个数×元素单元量L。 故n维数组A[u1][u2]…..[un],其中任一元素ai1....in的地址为:
Loc(ai1i2……in)=b+(i1•u2•u3• … •un+i2•u3•u4• …un+…+in-1•un+in)•L =b+(
…
A[i]
A(2) = A[m][n] =
ai0 ai1 …… aij ….… ain-1
………………………….
…
A[m-1]
am-10 am-11 …am-1j … am-1n-1
= (A[0]……A[i]……A[m-1] )-----线性表形式
2.数组的基本运算
多维数组是线性表的推广,而线性表是多维数组的特例。 在算法语言中,数组一旦生成,其元素的存储空间就固定下来,故数组 的运算一般不包括插入和删除这样的操作。对数组运算有: (1) 构造一个n维数组:Setarray(A,n,d1d2,......dn),即生成: A[d1][d2].....[dn](C语言中,1≤n≤8)。 (2) 撤消一个数组:Dearray(A),释放数组A的存储空间。 (3) 取值:Aget(A,i1,...,in,x),将A[i1][i2],...,[in]的值传给变量 x。 (4) 赋值:Assign(A,i1,...,in,x),将变量 x的值传给A[i1][i2].....[in]。
第5 章数组和广义表
2019/11/8
14
如果将三维数组推广到一般情况,即:用j1,j2, j3代替数组下标i,j,k;并且j1,j2,j3的下限为c1, c2,c3,上限分别为d1,d2,d3,每个元素占一个 存储单元。则三维数组中任意元素 a(j1,j2,j3)的地址为:
………
……
特点:
i=1, j=1,2; 当 1<i<n,j=i-1, i, i+1
i=n, j=n-1, n;
时,aij非零,其他元素均为零。
2019/11/8
21
三对角带状矩阵的压缩存储,以行序为主序进行存储, 并且只存储非零元素。其方法为:
1. 确定存储该矩阵所需的一维向量空间的大小
从三对角带状矩阵中可看出:除第一行和最后一行只有两 个元素外,其余各行均有3个非零元素。由此可得到一维向量
i(i-1)/2+j-1 当i>=j k=
j(j-1)/2+i-1 当i<j
2019/11/8
20
5.3.2 带状矩阵
带状矩阵:在矩阵A中,所有的非零元素都集中在以主对角 线为中心的带状区域中。最常见的是三对角带状矩阵。
a11 a12
a21 a22 a23
An×n =
a32 a33 a34 a43 a44 a45
Loc[i,j]=Loc[1,1]+n ×(i-1)+(j-1)
其中n为第2维的长度
如果每个元素占size个存储单元 ,则任意元 素aij的地址计算公式为:
Loc[i,j]=Loc[1,1] + (n×(i-1)+j-1)×size
数组和广义表 数据结构
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章 数组和广义表
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章-数组和广义表
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)。
第5章数组和广义表习题
一、选择题
1.设有一个10阶的对称矩阵A,采用压缩存储方式,以行序为主存储,a11为第一元素,其存储地址为1,每个元素占一个地址空间,则a85的地址为(B)。
i×(i-1)/2+j-1~~~~(i>=j)
8×7÷2+5=33因为a11从1开始所以要加1
A. 13
B. 33
C. 18
D. 40
2. 数组A[0..5,0..6]的每个元素占五个字节,将其按列优先次序存储在起始地址为1000的内存单元中,则元素A[5,5]的地址是( A)。
所求=a+(j*n+j)*l
A. 1175
B. 1180
C. 1205
D. 1210
3. 若对n阶对称矩阵A以行序为主序方式将其下三角形的元素(包括主对角线上所有元素)依次存放于一维数组B[1..(n(n+1))/2]中,则在B中确定aij(i<j)的位置k的关系为(B)。
A. i*(i-1)/2+j
B. j*(j-1)/2+i
C. i*(i+1)/2+j
D. j*(j+1)/2+i
4. A[N,N]是对称矩阵,将下面三角(包括对角线)以行序存储到一维数组T[N(N+1)/2]中,则对任一上三角元素a[i][j]对应T[k]的下标k是(B)。
A. i(i-1)/2+j
B. j(j-1)/2+i
C. i(j-i)/2+1
D. j(i-1)/2+1
二、填空题
1. 已知数组A[0..9,0..9]的每个元素占5个存储单元,将其按行优先次序存储在起始地址为1000的连续的内存单元中,则元素A[6,8]的地址为_______。
2.设n行n列的下三角矩阵A已压缩到一维数组B[1..n*(n+1)/2]中,若按行为主序存储,则A[i,j]对应的B中存储位置为_______。
3.己知三对角矩阵A【1..9,1..9】的每个元素占2个单元,现将其三条对角线上的元素逐行存储在起始地址为1000的连续的内存单元中,则元素A[7,8]的地址为______。
三、应用题
设对角线矩阵A=(行列下标i ,j 满足:1≤i,j≤5)
(1)若将矩阵A压缩存储到数组S 中:
试求出A中已存储之元素的行列下标(i,j)与S中元素的下标K之间的关系
(2)若将A视为稀疏矩阵时,画出其三元组表形式压缩存储表。
(3)若将A视为稀疏距阵时,请画出其行逻辑链接顺序表。