版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、数 据 结 构,第 5 章 数组和广义表,引言,数组是一种人们非常熟悉的数据结构,几乎所有的程序设计语言都支持这种数据结构或将这种数据结构设定为语言的固有类型。数组这种数据结构可以看成是线性表的推广。 科学计算中涉及到大量的矩阵问题,在程序设计语言中一般都采用矩阵来存储,被描述成一个二维数组。但当矩阵规模很大且具有特殊结构(对角矩阵、三角矩阵、对称矩阵、稀疏矩阵等),为减少程序的时间和空间需求,采用自定义的描述方式。 广义表是另一种推广形式的线性表,是一种灵活的数据结构,在许多方面有广泛的应用。,主要内容,5.1 数组的定义 5.2 数组的顺序表示和实现 5.3 矩阵的压缩存储 5.4 广义表
2、的定义 5.5 广义表的存储结构,5.1 数组的定义,数组是一组偶对(下标值,数据元素值)的集合。在数组中,对于一组有意义的下标,都存在一个与其对应的值。一维数组对应着一个下标值,二维数组对应着两个下标值,如此类推。 数组是由n(n1)个具有相同数据类型的数据元素a1,a2,an组成的有序序列,且该序列必须存储在一块地址连续的存储单元中。 数组中的数据元素具有相同数据类型。 数组是一种随机存取结构,给定一组下标,就可以访 问与其对应的数据元素。 数组中的数据元素个数是固定的。,二维数组的特点:,一维数组的特点:,1个下标,ai 是ai+1的直接前驱,2个下标,每个元素ai,j受到两个关系(行关
3、系和列关系)的约束:,一个mn的二维数组可以看成是m行的一维数组,或者n列的一维数组。,一个n维数组可以看成是由若干个n1维数组组成的线性表。,5.1 数组的定义,N维数组的特点:,n个下标,每个元素受到n个关系约束,5.1 数组的定义,数组的抽象数据类型,ADT Array 数据对象:ji= 0,1,bi-1 , i=1,2, ,n ; D = aj1j2jn | n0称为数组的维数,bi是数组第i维的长度,ji是数组元素第i维的下标,aj1j2jnElemSet 数据关系:R = R1, R2, , Rn Ri=|0jkbk-1 , 1kn且ki,0jibi-2, aj1j2 jijn ,
4、 aj1j2 ji+1jn D i=1,2,n 基本操作: ADT Array,由上述定义知,n维数组中有b1b2 bn个数据元素, 每个数据元素都受到n维关系的约束。,5.1 数组的定义,二维数组举例说明,以二维数组为例讨论。将二维数组看成是一个定长的线性表,其每个元素又是一个定长的线性表。 设二维数组A=(aij)mn,则 A=(0,1,p) (p=m-1或n-1) 其中每个数据元素j是一个列向量(线性表) : j =(a0j , a1j , , am-1,j) 0jn-1 或是一个行向量: i =(ai0 ,ai1 ,ai,n-1) 0im-1 如下图所示。,二维数组图例形式,(a) 矩
5、阵表示形式,(b) 行向量的一维数组形式,(c) 列向量的一维数组形式,5.1 数组的定义,二维数组举例说明,5.2 数组的顺序表示和实现,数组一般不做插入和删除操作,也就是说,数组一旦建立,结构中的元素个数和元素间的关系就不再发生变化。因此,一般都是采用顺序存储的方法来表示数组。 问题:计算机的内存结构是一维(线性)地址结构,对于多维数组,将其存放(映射)到内存一维结构时,有个次序约定问题。即必须按某种次序将数组元素排成一列序列,然后将这个线性序列存放到内存中。 二维数组是最简单的多维数组,以此为例说明多维数组存放(映射)到内存一维结构时的次序约定问题。,5.2 数组的顺序表示和实现,通常有
6、两种顺序存储方式 行优先顺序(Row Major Order) :将数组元素按行排列,第i+1个行向量紧接在第i个行向量后面。对二维数组,按行优先顺序存储的线性序列为: a00,a01,a0,n-1, a10,a11,a1,n-1, , am-1,0, am-1,1 ,am-1,n-1 PASCAL、C是按行优先顺序存储的,如图所示。,行优先顺序,5.2 数组的顺序表示和实现,列优先顺序, 列优先顺序(Column Major Order) :将数组元素按列向量排列,第j+1个列向量紧接在第j个列向量之后,对二维数组,按列优先顺序存储的线性序列为: a00 ,a10,am-1,0, a01,a
7、11,am-1,1, , a0,n-1 ,a1,n-1, ,am-1,n-1 FORTRAN是按列优先顺序存储的,如图所示。,5.2 数组的顺序表示和实现,设有二维数组A=(aij)mn,若每个元素占用的存储单元数为l(个),LOCa00表示元素a00的首地址,即数组的首地址。 以“行优先顺序”存储 (1) 第1行中的每个元素对应的(首)地址是: LOCa0j=LOCa00+jl j=0,1, ,n-1 (2) 第2行中的每个元素对应的(首)地址是: LOCa1j=LOCa00+nl +jl j=0,1, ,n-1 (3) 第m行中的每个元素对应的(首)地址是: LOCam-1,j=LOCa0
8、0+(m-1)nl +jl j=0,1, ,n-1,5.2 数组的顺序表示和实现,由此可知,二维数组中任一元素aij的(首)地址是: LOCaij=LOCa00+in +jl i=0,1, ,m-1 j=0,1, ,n-1 (5-1) 对于三维数组A=(aijk) r mn,若每个元素占用的存储单元数为l(个),LOCa00表示元素a000的首地址,即数组的首地址。以“行优先顺序”存储在内存中。 三维数组中任一元素aijk的(首)地址是: LOC(aijk)=LOCa000+imn+jn+kl (5-2),推而广之,对n维数组A=(aj1j2jn) ,若每个元素占用的存储单元数为l(个),LO
9、Ca00 0表示元素a00 0的首地址。则以“行优先顺序”存储在内存中。,5.2 数组的顺序表示和实现,n维数组中任一元素aj1j2jn的(首)地址是: LOCaj1j2jn=LOCa00 0+(b2bn)j1 + (b3bn)j2+ + bnjn-1+ jn l (5-3),#define MAX_ARRAY_DIM 8 /假设最大维数为8 typedef struct ELemType *base; /数组元素基址 int dim; /数组维数 int *bound; /数组各维长度信息保存区基址 int *constants; /数组映像函数常量的基址 Array;,即存储单元为1时,c
10、i信息保存区,N维数组的顺序存储表示,5.2 数组的顺序表示和实现,Status InitArray(Array ,数组的基本操作,5.2 数组的顺序表示和实现,数组的基本操作,5.2 数组的顺序表示和实现,va_list ap; /ap为va_list类型,是存放变长参数表信息的类型 va_start(ap,dim); /使ap指向第一个可选参数。 for(i=0;i=0;-i) A.constantsi=A.boundsi+1*A.constantsi+1; return OK; ,数组的基本操作,5.2 数组的顺序表示和实现,Status DestroyArray(Array ,数组的基
11、本操作,5.2 数组的顺序表示和实现,Status Locate(Array A,va_list ap,int ,数组的基本操作,5.2 数组的顺序表示和实现,Status Value(Array A,ElemType ,数组的基本操作,5.2 数组的顺序表示和实现,Status Assign(Array ,5.3 矩阵的压缩存储,在科学与工程计算问题中,矩阵是一种常用的数学对象,在高级语言编程时,通常将一个矩阵描述为一个二维数组。这样,可以对其元素进行随机存取,各种矩阵运算也非常简单。 对于高阶矩阵,若其中非零元素呈某种规律分布或者矩阵中有大量的零元素,若仍然用常规方法存储,可能存储重复的非
12、零元素或零元素,将造成存储空间的大量浪费。对这类矩阵进行压缩存储: 多个相同的非零元素只分配一个存储空间; 零元素不分配空间。,5.3 矩阵的压缩存储,特殊矩阵-对称矩阵,若一个n阶方阵A=(aij)nn中的元素满足性质: aij=aji 1i,jn且ij 则称A为对称矩阵,如下图所示。,5.3 矩阵的压缩存储,特殊矩阵-对称矩阵,对称矩阵中的元素关于主对角线对称,因此,让每一对对称元素aij和aji(ij)分配一个存储空间,则n2个元素压缩存储到n(n+1)/2个存储空间,能节约近一半的存储空间。 不失一般性,假设按“行优先顺序”存储下三角形(包括对角线)中的元素。 设用一维数组(向量)sa
13、n(n+1)/2存储n阶对称矩阵,如下图所示。为了便于访问,必须找出矩阵A中的元素的下标值(i,j)和向量sak的下标值k之间的对应关系。,5.3 矩阵的压缩存储,特殊矩阵-对称矩阵,若ij:ai j在下三角形中,直接保存在sa中。ai j之前的i-1行共有元素个数: 1+2+(i-1)=i(i-1)/2 而在第i行上,ai j之前恰有j-1个元素,因此,元素ai j保存在向量sa中时的下标值k之间的对应关系是: k=i(i-1)/2+j-1 ij 若i(k-1)/2时, ai j=0,5.3 矩阵的压缩存储,特殊矩阵-对角矩阵,对角矩阵可按行优先顺序或对角线顺序,将其压缩存储到一个向量中,并
14、且也能找到每个非零元素和向量下标的对应关系。 仍然以三对角矩阵为例讨论。 当i=1,j=1、2,或i=n, j=n-1、n或 1in-1,j=i-1、i、i+1的元素aij外,其余元素都是0。 对这种矩阵,当以按“行优先顺序”存储时, 第1行和第n行是2个非零元素,其余每行的非零元素都要是3个,则需存储的元素个数为3n-2。,上图所示三对角矩阵的压缩存储形式。数组sa中的元素sak与三对角矩阵中的元素aij存在一一对应关系,在aij之前有i-1行,共有3(i-1)-1个非零元素,在第i行,有j-i+1个非零元素,这样,非零元素aij的地址为: LOCai j =LOCa11 +3(i-1)-1
15、+(j-i+1)l =LOCa11+(2i+j-3)l 上例中,a34对应着sa7 , k=2i+j-3=23+4-3=7 称sa03n-3是n阶三对角矩阵A的压缩存储。 上述各种特殊矩阵,其非零元素的分布都是有规律的,因此总能找到一种方法将它们压缩存储到一个向量中,并且一般都能找到矩阵中的元素与该向量的对应关系,通过这个关系,仍能对矩阵的元素进行随机存取。,5.3 矩阵的压缩存储,特殊矩阵-对角矩阵,5.3 矩阵的压缩存储,稀疏矩阵(Sparse Matrix):对于稀疏矩阵,目前还没有一个确切的定义。设矩阵A是一个nm的矩阵中有s个非零元素,设 =s/(nm),称为稀疏因子,如果某一矩阵的
16、稀疏因子满足0.05时称为稀疏矩阵,如图所示。,稀疏矩阵,5.3 矩阵的压缩存储,稀疏矩阵-三元组顺序表,对于稀疏矩阵,采用压缩存储方法时,只存储非0元素。必须存储非0元素的行下标值、列下标值、元素值。因此,一个三元组(i, j, aij)唯一确定稀疏矩阵的一个非零元素。 下图的稀疏矩阵A的三元组线性表为: ( (1,2,12), (1,3,9), (3,1,-3), (3,8,4), (4,3,24), (5,2,18), (6,7,-7), (7,4,-6),5.3 矩阵的压缩存储,稀疏矩阵-三元组顺序表,若以行序为主序,稀疏矩阵中所有非0元素的三元组,就可以得构成该稀疏矩阵的一个三元组顺
17、序表。相应的数据结构定义如下:, 三元组结点定义 #define MAX_SIZE 101 typedef int elemtype ; typedef struct int row ; /* 行下标 */ int col ; /* 列下标 */ elemtype value; /* 元素值*/ Triple ;, 三元组顺序表定义 typedef struct int rn ; /*行数 */ int cn ; /* 列数 */ int tn ; /*非0元素个数 */ Triple dataMAX_SIZE ; TMatrix ;,5.3 矩阵的压缩存储,稀疏矩阵-三元组顺序表,稀疏矩阵(
18、下图)及其相应的转置矩阵所对应的三元组顺序表(右图)。,5.3 矩阵的压缩存储,稀疏矩阵-矩阵转置,对于一个m行 n列的矩阵M,它的转置矩阵T是一个n行m列的矩阵。,5.3 矩阵的压缩存储,稀疏矩阵-矩阵转置,5.3 矩阵的压缩存储,稀疏矩阵-矩阵转置,答:肯定不正确! 除了: (1)每个元素的行下标和列下标互换(即三元组中的i和j互换); 还应该:(2)T的总行数mu和总列数nu与M值不同(互换); (3)重排三元组内元素顺序,使转置后的三元组也按行(或列)为主序有规律的排列。,上述(1)和(2)容易实现,难点在(3)。,若采用三元组压缩技术存储稀疏矩阵,只要把每个元素的行下标和列下标互换,
19、就完成了对该矩阵的转置运算,这种说法正确吗?,有两种实现方法,压缩转置 (压缩)快速转置,5.3 矩阵的压缩存储,稀疏矩阵-矩阵转置,矩阵M的三元组顺序表,M的转置矩阵T的三元组顺序表,5.3 矩阵的压缩存储,稀疏矩阵-矩阵转置,转置运算算法TransposeSMatrix(TSMatrix M, TSMatrix 2. 求M中各列第一个非零元在T.data中的下标cpot ; 3. 对M.data进行一次扫描, 遇到col列的第一个非零元三 元组时,按cpotcol 的位置,将其放至T.data中,当再 次遇到col列的非零元三元组时,只须顺序放到col列元 素的后面;,快速转置算法主要步骤
20、:,5.3 矩阵的压缩存储,稀疏矩阵-矩阵转置,2,2,8,1,1,0,0,1,3,5,2,7,8,9,i j v,i j v,M.data,T.data,1 2 12,2 1 12,第2列第一个非零元在b中的位置,1 3 9,第3列第一个非零元在b中的位置,3 1 9,3 1 -3,1 3 -3,3 6 14,6 3 14,4 3 24,3 4 24,5 2 18,2 5 18,6 1 15,1 6 15,6 4 -7,4 6 -7,4,第2列第二个非零元在b中的位置,6,5,快速转置算法图示,第3列第二个非零元在b中的位置,第1列第一个非零元在b中的位置,2,7,9,3,第4 列第一个非零
21、元在b中的位置,求各列第1个非零元在b中位置,求各列非零元个数,扫描M.data实现M到T 的转置,5.3 矩阵的压缩存储,稀疏矩阵-矩阵转置,Status FastTransposeSMatrix(TSMatrix M, TSMatrix /FastTransposeSMatrix,5.3 矩阵的压缩存储,稀疏矩阵-矩阵转置,时间复杂度分析 该算法利用两个辅助向量num 、cpos ,实现了对M.data一次扫描完成M到T 的转置。 从时间上看,算法中有四个并列的单循环,循环次数分别为nu、tu、tu和tu,因而总的时间复杂度为O(nu+tu),在M的非零元个数tu和munu 同等数量级时,
22、其时间复杂度为O( munu) 。由此可见,只有当tu munu时,使用快速转置算法才有意义。,5.3 矩阵的压缩存储,稀疏矩阵-行逻辑链接的三元组顺序表,将上述方法中的辅助向量cpot 固定在稀疏矩阵的三元组表中,用来指示“行”的信息。得到另一种顺序存储结构:行逻辑链接的三元组顺序表。其类型描述如下: #define MAX_ROW 100 typedef struct Triple dataMAX_SIZE ; /* 非0元素的三元组表 */ int rposMAX_ROW; /* 各行第一个非0位置表 */ int rn ,cn , tn ; /* 矩阵的行、列数和非0元个数 */ RL
23、SMatrix ;,5.3 矩阵的压缩存储,稀疏矩阵-矩阵乘法,设有两个矩阵:A=(aij)mn ,B=(bij)np 则: C=(cij)mp 其中 cij=aikbkj 1kn , 1im ,1jp 经典算法是三重循环: for ( i=1 ; i=m ; +i) for ( j=1 ; j=p ; +j) cij=0 ; for ( k=1 ; k=n ; +k) cij= cij+aikbkj; 此算法的复杂度为O(mnp)。,5.3 矩阵的压缩存储,稀疏矩阵-矩阵乘法,设有两个稀疏矩阵A=(aij)mn ,B=(bij)np ,其存储结构采用行逻辑链接的三元组顺序表。 算法思想:对于
24、A中的每个元素a.datap(p=1, 2, , a.tn),找到B中所有满足条件: a.datap.col=b.dataq.row的元素b.dataq,求得a.datap.valueb.dataq.value,该乘积是cij中的一部分。求得所有这样的乘积并累加求和就能得到cij。 为得到非0的乘积,只要对a.data1a.tn 中每个元素(i,k,aik)(1ia.rn,1k) ,找到b.data中所有相应的元素(k,j,bkj)(1kb.rn,1j) 相乘即可。则必须知道矩阵B中第k行的所有非0元素,而b.rpos 向量中提供了相应的信息。,5.3 矩阵的压缩存储,稀疏矩阵-矩阵乘法,b.
25、rposrow指示了矩阵B的第row行中第一个非0元素在b.data 中的位置(序号),显然,b.rposrow+1-1指示了第row行中最后一个非0元素在b.data 中的位置(序号) 。最后一行中最后一个非0元素在b.data 中的位置显然就是b.tn 。 两个稀疏矩阵相乘的算法及其复杂度分析见课本中算法5.3,5.3 矩阵的压缩存储,稀疏矩阵-十字链表,对于稀疏矩阵,当非0元素的个数和位置在操作过程中变化较大时,采用链式存储结构表示比三元组的线性表更方便。 矩阵中非0元素的结点所含的域有:行、列、值、行指针(指向同一行的下一个非0元)、列指针(指向同一列的下一个非0元)。结点的结构如图所
26、示。,十字链表结点结构,5.3 矩阵的压缩存储,稀疏矩阵-十字链表,由定义知,稀疏矩阵中同一行的非0元素的由right指针域链接成一个行链表, 同一列的非0元素由down指针域链接成一个列链表。则每个非0元素既是某个行链表中的一个结点,同时又是某个列链表中的一个结点,所有的非0元素构成一个十字交叉的链表。称为十字链表。 此外,还可用两个一维数组分别存储行链表的头指针和列链表的头指针。,5.3 矩阵的压缩存储,稀疏矩阵-十字链表,typedef struct OLNode int row , col ; /* 行号和列号 */ elemtype value ; /* 元素值 */ struct
27、Clnode *down , *right ; OLNode ; /* 非0元素结点 */ typedef struct int rn; /* 矩阵的行数 */ int cn; /* 矩阵的列数 */ int tn; /* 非0元素总数 */ OLNode *rhead ; OLNode *chead ; CrossList ; /*存放行列头结点数组结构*/,对于下图中的稀疏矩阵A ,对应的十字交叉链表如右图所示,结点的描述如下:,5.3 矩阵的压缩存储,稀疏矩阵-十字链表,5.4 广义表的定义,广义表也称为列表,是线性表的一种扩展,也是数据元素的 有限序列。 记作:LS= (1, 2。n)
28、。其中i既可以是单个 元素,也可以是广义表(见课本抽象数据定义)。,说明: 1)广义表的定义是一个递归定义,因为在描述广义表时又用到了广义表; 2)在线性表中数据元素是单个元素,而在广义表中, 元素可是以单个元素称为原子,也可以是广义表,称为广义表的子表; 3)n 是广义表长度;,5.4 广义表的定义,下面是一些广义表的例子:,广义表的术语:,A = ( ) 空表,表长为0; B = (e) B中只有一个元素e,表长为1; C = (a,(b,c,d) C的表长为2,两个元素分别为 a 和子表(b,c,d); D = (A,B,C) D 的表长为3,它的三个元素 A,B,C 广义表;,长度:元
29、素个数n (注意子表是一个数据元素); 单元素:一般用小写字母表示; 子表: 一般用大写字母表示; 表头: 当广义表LS 非空时,称第一个元素为L的表头,其余元素组成的表称为LS的表尾;,5.4 广义表的定义,例如: B = (e) 表头:e 表尾 ( ) C = (a,(b,c,d) 表头:a 表尾 (b,c,d) D = (A,B,C) 表头:A 表尾 (B,C),若广义表不空,则可分成表头和表尾, 反之,一对表头和表尾可唯一确定广义表,5.4 广义表的定义,广义表深度:简单说就是表的嵌套层次(括号的层数), 定义为: LS = ( d1, d2 , ,dn ) depth ( LS )
30、= maxdepth(d1), depth(d2), ,depth(dn) + 1 0 di 是单元素 depth ( di ) = 1 di 是空表,5.4 广义表的定义,广义表及其示例,5.4 广义表的定义,广义表的基本操作 1) 创建空的广义表L; 2) 销毁广义表L; 3) 已有广义表L,由L复制得到广义表T; 4) 求广义表L的长度; 5) 求广义表L的深度; 6) 判广义表L是否为空; 7) 取广义表L的表头; 8) 取广义表L的表尾; 9) 在L中插入元素作为L的第一个元素; 10)删除广义表L的第一个元素,并e用返回其值; 11)遍历广义表L,用函数visit( )处理每个元素;,广义表的基本操作,广义表的重要结论: (1) 广义表的元素可以是原子,也可以是子表,子表的元素又可以是子表, 。即广义表是一个多层次的结构。 (2) 广义表可以被其它广义表所共享,也可以共享其它广义表。广义表共享其它广义表时通过表名引用(例如D=(A,B,C),其中A,B,C分别是三个广义表)。 (3) 广义表本身可以是一个递归表。 (4) 根据对表头、表尾的定义,任何一个非空广义表的表头
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 咖啡豆积分兑换政策
- 营销代理合同范本
- 五金交电灰土工程协议
- 智能工厂建设项目招投标流程
- 电商企业总监招聘合同范文
- 智能客服系统开发招投标文件
- 草原消防班组施工合同
- 旅游景点外墙装修合同
- 通信企业销售总经理招聘协议
- 河道城市给水工程合同
- 新概念英语第二册课文(全中文)
- 宇通客车CAN总线系统培训教材课件
- DB4401-T 10.5-2019 +反恐怖防范管理++第5部分:教育机构-(高清现行)
- 广东深圳市福田区选用机关事业单位辅助人员和社区专职工作者365人模拟试卷【共500题附答案解析】
- 【课件】 我们怎样鉴赏美术作品 课件-2022-2023学年高中美术湘美版(2019)美术鉴赏
- 国家一等奖《包身工》优质课件
- (本科)新编大学英语写作revised chapter 2ppt课件(全)
- 表格02保洁质量评分表
- 《虞美人》课件(共30张PPT)
- 上海中、低压电网配置原则及典型设计
- 公共经济学ppt课件(完整版)
评论
0/150
提交评论