1 / 42

数 据 结 构

数 据 结 构. 刘家芬 Sept 2011. 第五章 数组和广义表. 数组是大家非常熟悉的数据结构,可以看成是一种特殊形式的线性表。 广义表是另一种特殊形式的线性表,在许多方面有广泛的应用。 数组和广义表的特殊性在于:表中的元素本身也是一种数据结构。. 本章目标. 5.1 数组的定义 5.2 数组的顺序表示和实现 5.3 矩阵的压缩存储 5.3.1 特殊矩阵 5.3.2 稀疏矩阵 5.4 广义表的定义 5.5 广义表的存储结构. 5.1 数组的定义. 数组的程序设计语言定义

alpha
Download Presentation

数 据 结 构

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 数 据 结 构 刘家芬 Sept 2011

  2. 第五章 数组和广义表 • 数组是大家非常熟悉的数据结构,可以看成是一种特殊形式的线性表。 • 广义表是另一种特殊形式的线性表,在许多方面有广泛的应用。 • 数组和广义表的特殊性在于:表中的元素本身也是一种数据结构。

  3. 本章目标 5.1 数组的定义 5.2 数组的顺序表示和实现 5.3 矩阵的压缩存储 5.3.1 特殊矩阵 5.3.2 稀疏矩阵 5.4 广义表的定义 5.5 广义表的存储结构

  4. 5.1 数组的定义 • 数组的程序设计语言定义 • int a[10]; int b[3][5]; • 数组是由n(n>1)个具有相同数据类型的数据元素a1,a2,…,an组成的有序序列,且该序列必须存储在一块地址连续的存储单元中。 • 数组中的数据元素具有相同数据类型。 • 数组是一种随机存取结构,给定一组下标,就可以访问与其对应的数据元素。 • 数组中的数据元素个数是固定的。 • 多维数组的抽象数据类型定义

  5. n维数组 • n维数组中有b1b2 … bn个数据元素,每个数据元素都受到n维关系的约束。 • 数组中的每个数据元素都对应于一组下标,每个下标的取值范围是0≤ji≤bi-1,称为第i维的长度。 • n=1时,n维数组是一个定长的线性表。

  6. a00 a01 … a0,n-1 a10 a11 … a1,n-1 … … … … … am-1,0 am-1,1 …am-1,n-1 A= n维数组的直观定义 • 设二维数组A=(aij)mn,则 A=(α0,α1,…,αp) (p=m-1或n-1) 其中每个数据元素αj是一个列向量(线性表) : αj =(a0j ,a1j ,…,am-1,j) 1≦j≦n-1 或是一个行向量: αi =(ai0 ,ai0 ,…,ai,n-1) 1≦i≦m-1

  7. 5.2数组的顺序表示和实现 • 数组一般不做插入和删除操作,也就是说,数组一旦建立,结构中的元素个数和元素间的关系就不再发生变化。因此,一般都是采用顺序存储的方法来表示数组。 • 问题:计算机的内存结构是一维地址结构,对于多维数组,将其映射到一维结构时,有个次序约定问题。 • 即必须按某种次序将数组元素排成一列序列,然后将这个线性序列存放到内存中。

  8. 数组的顺序存储 通常有两种顺序存储方式: • 以行序为主序 (Row Major Order) :将数组元素按行排列,第i+1个行向量紧接在第i个行向量后面。 • PASCAL、C是按行优先顺序存储的。 • 以列序为主序(Column Major Order) :将数组元素按列向量排列,第j+1个列向量紧接在第j个列向量之后。 • FORTRAN是按列优先顺序存储的

  9. 数组的顺序存储 • 对n维数组A=(aj1 j2…jn) ,LOC[a0,0, …, 0]表示元素a0,0, …, 0的地址。假设每个数据元素占L个存储单元,若以行序为主序存储,n维数组中任一元素aj1 j2… jn的地址是: LOC[aj1j2…jn]=LOC[a0,0, …,0]+ [(b2…bn)j1+ (b3…bn)j2+ … + bn(jn-1-1) + (jn-1)] L

  10. 数组的顺序存储

  11. 矩阵的压缩存储 • 在科学与工程计算问题中,矩阵是一种常用的数学对象。 • 在高级语言编程时,通常将一个矩阵描述为二维数组。 • 对于高阶矩阵,若其中非零元素呈某种规律分布或者矩阵中有大量的零元素,若仍用常规方法存储,可能存储重复的非零元素或零元素,将造成存储空间的大量浪费。对这类矩阵进行压缩存储: • 多个相同的非零元素只分配一个存储空间。 • 零元素不分配空间。

  12. 1 5 1 3 7 a11 a21 a22 a31 a32 a33 … … … … an1 an2 … ann 5 0 8 0 0 A= A= 1 8 9 2 6 3 0 2 5 1 7 0 6 1 3 特殊矩阵 • 特殊矩阵:是指非零元素或零元素的分布有一定规律的矩阵。 • 若一个n阶方阵A=(ai j)nn中的元素满足性质: ai j=aj i 1≦i, j≦n且i≠j 则称A为对称矩阵。

  13. 1 5 1 3 7 a11 a21 a22 a31 a32 a33 … … … … an1 an2 … ann 5 0 8 0 0 A= A= 1 8 9 2 6 3 0 2 5 1 7 0 6 1 3 对称矩阵的存储 • 对称矩阵中的元素关于主对角线对称,故只要存储矩阵中上三角或下三角中的元素即可。 • 问:需存储多少个元素? • 不失一般性,假设用一维数组sa[n(n+1)/2]以行序为主序存放下三角的元素:

  14. 对称矩阵的存储 • i≥j:aij 在下三角形中,直接保存在sa中。 • aij之前的i-1行共有元素个数:1+2+…+(i-1)=i(i-1)/2 • 第i行上,aij之前有j-1个元素 • 元素aij保存在向量sa中时的下标值k之间的对应关系: k=i(i-1)/2+j-1 i ≥ j • i<j:aij在上三角矩阵中 • aij=aji,在向量sa中保存的是aji。因此 • k=j(j-1)/2+i-1 i<j

  15. 其他矩阵 • 三角矩阵 • 对角矩阵

  16. 0 12 9 0 0 0 0 0 0 0 0 0 0 0 0 0 -3 0 0 0 0 0 0 4 0 0 24 0 0 2 0 0 A= 0 18 0 0 0 0 0 0 0 0 0 0 0 0 -7 0 0 0 0 -6 0 0 0 0 稀疏矩阵示例 稀疏矩阵 • 设矩阵A是一个nm的矩阵,其中有s个非零元素,设δ=s/(nm),δ为稀疏因子。 • 矩阵的稀疏因子δ≦0.05时则称为稀疏矩阵

  17. 稀疏矩阵的压缩存储 • 由于非零元素的分布没有规律,存储非零元素的同时,还必须记下它所在的行和列的位置(i,j)。 • 因此稀疏矩阵可由表示非零元的值、及其行列数组成的三元组,以及矩阵行列数唯一确定。

  18. 三元组表示法 • 请写出矩阵M的三元组表示. • 稀疏矩阵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)这一对行、列值描述。

  19. 三元组顺序表

  20. 稀疏矩阵的转置 • 一个m×n的矩阵A,它的转置B是一个n×m的矩阵,且a[i][j]=b[j][i],0≦i≦m,0≦j≦n,即A的行是B的列,A的列是B的行 • 如何进行转置?

  21. 矩阵转置 • 将矩阵的行、列下标值交换 • 将每个三元组中的i、j相互交换; • 重排三元组之间的顺序,使得交换后仍然按行优先顺序存储。

  22. 矩阵转置方法一 • 按照b.data中三元组的次序依次在a.data中找到相应的三元组进行转置。即按照矩阵的列序进行转置。 • 对A中的每一列,通过从头至尾扫描三元表a.data,找出所有列号等于col的那些三元组,将它们的行号和列号互换后依次放入b.data中,即可得到B的按行优先的压缩存储表示。

  23. 稀疏矩阵的转置算法

  24. 矩阵转置方法二 • 按照a.data中三元组的次序进行转置,并将转置后的三元组放到b中适当的位置。 • 若能预先确定原矩阵A中每一列的(即B中每一行)第一个非0元素在b.data中应有的位置,则在作转置时就可直接放在b.data中恰当的位置。因此,应先求得A中每一列的非0元素个数。 • 附设两个辅助向量num[ ]和cpot[ ] 。 • num[col]:统计A中第col列中非0元素的个数; • cpot[col] :指示A中第一个非0元素在b.data中的恰当位置。

  25. 稀疏矩阵的转置算法

  26. 稀疏矩阵的另一种存储方式 • 为了便于快速存取任一行的非零元,需要知道每行的第一个非零元在三元组表中的位置。 • 在三元组表示法的基础上,将算法二中用来指示行信息的辅助矩阵cpot固定在存储结构中,就得到了稀疏矩阵的另一种顺序存储方式:带行链接信息的三元组表。

  27. 稀疏矩阵的乘法 • 矩阵相乘的经典算法 :Q= M * N,其中M是m1*n1矩阵,N是m2*n2矩阵 并且n1=m2 • 稀疏矩阵相乘的思想 P101

  28. 稀疏矩阵的第三种存储方式 • 对于稀疏矩阵,当非0元素的个数和位置在操作过程中变化较大时,采用链式存储结构表示比三元组表更方便。

  29. row col value down right 十字链表存储法 • 矩阵中非0元素的结点所含的域有:行、列、非零元的值、行指针(指向同一行的下一个非0元)、列指针(指向同一列的下一个非0元)。其次,十字交叉链表还有一个头结点。 结点结构

  30. 十字链表存储法 • 十字链表存储法下的矩阵相加思想P105

  31. 广义表 • 广义表是线性表的推广和扩充。 • 线性表定义为:n个元素a1, a2 ,…, an的有穷序列,该序列中的所有元素具有相同的类型。 • 如果允许线性表的元素包含某种数据结构,就产生了广义表的概念。 • 广义表记做LS=(a1, a2 ,…, an),线性表的定义中ai是单个元素,而广义表中ai可以是单个元素,也可以是广义表,分别成为广义表LS的原子和子表。

  32. 广义表相关的定义 • a1(表中第一个元素)称为表头; • 其余元素组成的子表 (a2, a3, …, an)称为表尾; • 广义表中所包含的元素(包括原子和子表)的个数称为表的长度。 • 广义表中括号的最大层数称为表的深度。

  33. 关于广义表 • 广义表是一个多层次的结构:广义表的元素可以是原子,也可以是子表;子表的元素又可以是子表。 • 广义表可以被其它广义表所共享,只需通过表名引用。 • 广义表本身可以是一个递归表。 • 根据对表头、表尾的定义,任何一个非空广义表的表头可以是原子,也可以是子表, 而表尾必定是广义表。

  34. 广义表的存储结构 • 顺序存储结构 • 链式存储结构 • 由于广义表中的数据元素具有不同的结构(或为原子,或为列表),无法用顺序结构存储,通常采用链式存储结构。每个元素用一个结点表示。 • 广义表中有两类结点: • 原子结点用来表示原子项,由标志域,值域组成。 • 表结点用来表示广义表项,由标志域,表头指针域,表尾指针域组成。

  35. 广义表的形式定义

  36. 广义表存储示例

  37. 广义表存储总结 • 若广义表为空,表头指针为空;否则,表头指针总是指向一个表结点,其中hp指向广义表的表头结点(或为原子结点,或为表结点) ,tp指向广义表的表尾(表尾为空时,指针为空,否则必为表结点)。 • 容易分清广义表中原子和列表所在层次。 • 最高层的表结点个数即为广义表的长度。

  38. Have FUN !

More Related