第五章 数组和广义表

50
第第第 第第第第第第 第第第 第第第第第第 第第第第第 一、: 第第第第第 一、: 第第第第第第第第第第第第第第第第第第第第第第第第 第第第第第第第第第第第第第第第第第第第第第第第第第第第第 第第第第第第 第第第第第第第第 第第第第第第第第第第第 、;。 第第第第第第 第第第第第第第第 第第第第第第第第第第第 、;。

description

第五章 数组和广义表. 一、教学内容: 数组的定义和顺序存储方式; 特殊矩阵及稀疏矩阵的压缩存储; 广义表的概念、表示及基本操作;广义表存储结构的实现。. 第五章 数组和广义表. 二、教学要求: 掌握一维数组以及多维数组的存储和表示方法,能计算二维数组任一元素的存贮地址; 掌握对特殊矩阵进行压缩存储时的下标变换公式,掌握稀疏矩阵的三元组表示方法及矩阵转置算法思想。 掌握广义表的结构特点及其基本运算,了解广义表存储表示方法。. 第五章 数组和广义表. 教学重点: 数组的定义 , 数组的顺序表示方法,矩阵的压缩存储。 教学难点: - PowerPoint PPT Presentation

Transcript of 第五章 数组和广义表

第五章 数组和广义表第五章 数组和广义表一、教学内容:一、教学内容: 数组的定义和顺序存储方式; 数组的定义和顺序存储方式; 特殊矩阵及稀疏矩阵的压缩存储;特殊矩阵及稀疏矩阵的压缩存储; 广义表的概念、表示及基本操作;广义表广义表的概念、表示及基本操作;广义表

存储结构的实现。存储结构的实现。

第五章 数组和广义表第五章 数组和广义表二、教学要求:二、教学要求: 掌握一维数组以及多维数组的存储和表示掌握一维数组以及多维数组的存储和表示

方法,能计算二维数组任一元素的存贮地方法,能计算二维数组任一元素的存贮地址;址;

掌握对特殊矩阵进行压缩存储时的下标变掌握对特殊矩阵进行压缩存储时的下标变换公式,掌握稀疏矩阵的三元组表示方法换公式,掌握稀疏矩阵的三元组表示方法及矩阵转置算法思想。及矩阵转置算法思想。

掌握广义表的结构特点及其基本运算,了掌握广义表的结构特点及其基本运算,了解广义表存储表示方法。解广义表存储表示方法。

第五章 数组和广义表第五章 数组和广义表教学重点:教学重点: 数组的定义 数组的定义 , , 数组的顺序表示方法,矩数组的顺序表示方法,矩

阵的压缩存储。 阵的压缩存储。 教学难点:教学难点: 矩阵的压缩存储、广义表存储结构、广义矩阵的压缩存储、广义表存储结构、广义

表的递归算法。表的递归算法。

第五章 数组和广义表第五章 数组和广义表

5.1 5.1 数组的定义数组的定义5.2 5.2 数组的顺序表示和实现(数组的顺序表示和实现(重点和难点重点和难点))5.3 5.3 矩阵的压缩存储 (矩阵的压缩存储 (重点和难点重点和难点)) 5.3.1 5.3.1 特殊矩阵特殊矩阵 5.3.2 5.3.2 稀疏矩阵稀疏矩阵5.4 5.4 广义表的定义及存储结构(广义表的定义及存储结构(重点和难重点和难

点点))

5.1 5.1 数组数组

数组数组可看成是一种可看成是一种特殊的线性表特殊的线性表,其特殊在于,表,其特殊在于,表中的中的数据元素本身也是一种线性表数据元素本身也是一种线性表。。

一维数组:一维数组: A1=A1= (( aa00 ,, aa11 ,, aa22 ,,…………,, aan-1n-1 ))二维数组: 二维数组: aa0000 a a0101 …… a …… a0n-10n-1

A2= ……A2= ……

aam-10m-10 a am-11m-11 a am-1n-1m-1n-1

又可表示为:又可表示为: A2=A2= ( ( aa00 ,, aa11 ,, aa22 ,,…………,, aan-1n-1 ))其中 其中 aaii== (( aa0i0i ,, aa1i1i ,,…………,, aam-1im-1i )为列向量。)为列向量。

5.1 5.1 数组数组

NN 维数组:维数组: b1×b2×b3×……×bnb1×b2×b3×……×bn 也可以表示为一个线性表也可以表示为一个线性表 ( ( aa00 ,, aa11 ,, aa22 ,,…………,, aabn -1bn -1 ))表中的每个元素均为一个表中的每个元素均为一个 N-1N-1 维的数组。维的数组。数组的抽象数据类型数组的抽象数据类型((了解)了解) 数组一旦被定义,它的维数和维界就不再数组一旦被定义,它的维数和维界就不再改变。因此,除了结构的改变。因此,除了结构的初始化初始化和和销毁销毁之之外,数组只有外,数组只有存取存取元素和元素和修改修改元素值的操元素值的操作。作。

第五章 数组和广义表第五章 数组和广义表5.1 5.1 数组的定义数组的定义5.2 5.2 数组的顺序表示和实现数组的顺序表示和实现5.3 5.3 矩阵的压缩存储矩阵的压缩存储 5.3.1 5.3.1 特殊矩阵特殊矩阵 5.3.2 5.3.2 稀疏矩阵稀疏矩阵5.4 5.4 广义表的定义及存储结构广义表的定义及存储结构

5.2 5.2 数组的顺序表示和实现数组的顺序表示和实现

类型特点类型特点 : :

1) 1) 只有引用型操作,没有加工型操作只有引用型操作,没有加工型操作 ; ;

2) 2) 数组是多维的结构,而存储空间是 一个数组是多维的结构,而存储空间是 一个一维的结构。 一维的结构。

有两种顺序映象的方式有两种顺序映象的方式 ::

1)1) 以行序为主序以行序为主序 ; ;

2)2) 以列序为主序以列序为主序 ;;

数组的顺序存储方式数组的顺序存储方式⑴⑴ 行优先顺序行优先顺序————将数组元素按行排列,第将数组元素按行排列,第 i+1i+1 个个行向量紧接在第行向量紧接在第 ii 个行向量后面。以二维数组为个行向量后面。以二维数组为例,按行优先顺序存储的线性序列为: 例,按行优先顺序存储的线性序列为: aa1111,a,a1212,…,a,…,a1n1n,a,a2121,a,a2222,…a,…a2n2n,……,a,……,am1m1,a,am2m2,…,a,…,amnmn

在在 PASCALPASCAL 、、 CC 语言中,数组就是按行优先语言中,数组就是按行优先顺序存储的。顺序存储的。

⑵⑵ 列优先顺序列优先顺序————将数组元素按列向量排列,第将数组元素按列向量排列,第j+1j+1 个列向量紧接在第个列向量紧接在第 jj 个列向量之后,个列向量之后, AA 的的m*nm*n 个元素按列优先顺序存储的线性序列为:个元素按列优先顺序存储的线性序列为:

aa1111,a,a2121,…,a,…,am1m1,a,a1212,a,a2222,…a,…am2m2,……,a,……,an1n1,a,an2n2,…,a,…,anmnm

在在 FORTRANFORTRAN 语言中,数组就是按列优先顺序存储语言中,数组就是按列优先顺序存储的。的。

例如: 数组 A b1×b2b1×b2

称为基地址或基址。

数组元素地址计算

二维数组 A 中任一元素 ai,j 的存储位置 LOC(i,j) = LOC(0,0) + (b2×i + j)×

a0,1 a0,0 a0,2

a1,0 a1,1 a1,2

a0,1 a0,0 a0,2 a1,0 a1,1 a1,2

L

L

数组元素地址计算数组元素地址计算 同样,三维数组同样,三维数组 AAb1×b2×b3b1×b2×b3按“行优先顺序”存按“行优先顺序”存储,元素储,元素 aaijkijk的地址计算函数为的地址计算函数为::

LOC(aLOC(aijkijk)=LOC(a)=LOC(a000000)+(i*b2*b3+j*b3+k)*L)+(i*b2*b3+j*b3+k)*L

结论结论 ::

只要知道开始元素的存放地址(即只要知道开始元素的存放地址(即基地址基地址),),维维数和每维的上、下界,以及每个数组元素所占用数和每维的上、下界,以及每个数组元素所占用的单元数的单元数,就可以将数组元素的存放地址表示为,就可以将数组元素的存放地址表示为其下标的线性函数。因此,数组中的任一元素可其下标的线性函数。因此,数组中的任一元素可以在相同的时间内存取,即顺序存储的数组是一以在相同的时间内存取,即顺序存储的数组是一个个随机存取随机存取结构。结构。

了解了解数组的顺序存贮表示和实现数组的顺序存贮表示和实现

例例 22 :已知二维数组:已知二维数组 Am,m 按行存储的元素地址公式是:按行存储的元素地址公式是: Loc(aLoc(aijij)= Loc(a)= Loc(a1111)+[(i-1)*m+(j-1)]*K , )+[(i-1)*m+(j-1)]*K , 按列按列存储的公式是?存储的公式是?

Loc(aLoc(aijij)=Loc(a)=Loc(a1111)+[()+[(jj-1)*m+(-1)*m+(ii-1)]*K -1)]*K

例 1 、一个二维数组 A ,行下标的范围是 1 到 6 ,列下标的范围是 0 到 7 ,每个数组元素用相邻的 6 个字节存储,存储器按字节编址。那么,这个数组的体积是 个字节。

288

例 3 、设数组 a[1…60, 1…70] 的基地址为 2048 ,每个元素占 2 个存储单元,若以列序为主序顺序存储,则元素 a[32,58] 的存储地址为 。8950

LOC(aij)=LOC(ac1 , c2)+[(j-c2)*b1+i-c1)]*L

答:请注意审题! 利用列优先通式:

第五章 数组和广义表第五章 数组和广义表5.1 5.1 数组的定义数组的定义5.2 5.2 数组的顺序表示和实现数组的顺序表示和实现5.3 5.3 矩阵的压缩存储矩阵的压缩存储 5.3.1 5.3.1 特殊矩阵特殊矩阵 5.3.2 5.3.2 稀疏矩阵稀疏矩阵5.4 5.4 广义表的定义及存储结构广义表的定义及存储结构

5.3 5.3 矩阵的压缩存储矩阵的压缩存储

矩阵的一般存贮表示矩阵的一般存贮表示 ?? 元素的访问元素的访问 ?? 矩阵类似二维数组,存储方式同二维数组。矩阵类似二维数组,存储方式同二维数组。 1 5 1 3 7 0 0 3 0 01 5 1 3 7 0 0 3 0 0 5 0 8 0 0 4 0 0 0 55 0 8 0 0 4 0 0 0 5A= 1 8 9 2 6 B= 0 0 0 0 7A= 1 8 9 2 6 B= 0 0 0 0 7 3 0 2 5 1 6 0 0 0 33 0 2 5 1 6 0 0 0 3 7 0 6 1 37 0 6 1 3

但以二维数组表示的特殊矩阵有重复元素值反复存储的缺点,但以二维数组表示的特殊矩阵有重复元素值反复存储的缺点,及高阶的稀疏矩阵时产生的问题及高阶的稀疏矩阵时产生的问题 ::1) 1) 零值元素占了很大空间零值元素占了很大空间 ; ; 2) 2) 计算中进行了很多和零值的运算,遇除法,还需判别除数计算中进行了很多和零值的运算,遇除法,还需判别除数

是否为零。是否为零。

5.3.15.3.1 特殊矩阵特殊矩阵

所谓特殊矩阵是指非零元素或零元素的所谓特殊矩阵是指非零元素或零元素的分布有一定规律分布有一定规律的矩阵,下的矩阵,下面我们讨论几种特殊矩阵的压缩存储。面我们讨论几种特殊矩阵的压缩存储。

11 、对称矩阵、对称矩阵 在一个在一个 nn 阶方阵阶方阵 AA 中,若元素满足下述性质:中,若元素满足下述性质: aaijij=a=ajiji 1≦i,j≦n 1≦i,j≦n

则称则称 AA 为对称矩阵。如下图便是一个为对称矩阵。如下图便是一个 55 阶对称矩阵。阶对称矩阵。 1 5 1 3 7 a1 5 1 3 7 a11

5 0 8 0 0 a5 0 8 0 0 a21 21 a a 22 22

1 8 9 2 6 a1 8 9 2 6 a3131 a a3232 a a3333

3 0 2 5 1 ………………..3 0 2 5 1 ……………….. 7 0 6 1 3 a7 0 6 1 3 an1n1 a a n2 n2 a a n3n3 … …

a a nnnn

对称矩阵对称矩阵 AA

在这个下三角矩阵中,第在这个下三角矩阵中,第 ii 行恰有行恰有 ii 个元素,元个元素,元素总数为:素总数为:

∑ ∑ (i)=(1+2+3+……+n)=n(n+1)/2(i)=(1+2+3+……+n)=n(n+1)/2

压缩的方法压缩的方法是首先将二维关系映射成一维关系,并只是首先将二维关系映射成一维关系,并只存储其中必要的存储其中必要的 n(n+1)/2n(n+1)/2 个(个(主对角线和下三角主对角线和下三角))元素内容,这些元素的元素内容,这些元素的存储顺序以行为主序存储顺序以行为主序。 。

因此,我们可以按图中箭头所指的次序将这些元素存因此,我们可以按图中箭头所指的次序将这些元素存放在一个向量放在一个向量 sa[0..n(n+1)/2-1]sa[0..n(n+1)/2-1] 中。中。

0 1 2 3 n(n-1)/2 0 1 2 3 n(n-1)/2 n(n+1)/2-1n(n+1)/2-1

i=1

i=n

aa1111 aa2121 aa2222 aa3131 ………… aan,n, 11 …………

aan,nn,n

为了便于访问对称矩阵为了便于访问对称矩阵 AA 中的元素,我们必须在中的元素,我们必须在 aaijij和和 sa[k]sa[k] 之间找一个对应关系。之间找一个对应关系。

若若 i≧ji≧j ,则,则 aai ji j 在下三角形中在下三角形中。 。 aai i j 之前的之前的 i-1i-1 行(从第行(从第

11 行到第行到第 i-1i-1 行)一共有行)一共有 1+2+…+(i-1)=i(i-1)/21+2+…+(i-1)=i(i-1)/2 个个

元素,在第元素,在第 ii 行上, 行上, a a i ji j 之前恰有之前恰有 j-1j-1 个元素(即个元素(即

aai1i1,a,ai2i2,a,ai3i3,…,a,…,aij-1ij-1 ),因此有:),因此有:

k=i*(i-1)/2+j-1 i≧jk=i*(i-1)/2+j-1 i≧j

若若 i<ji<j ,则,则 aaijij 是在上三角矩阵中是在上三角矩阵中。因为。因为 aaijij=a=ajiji ,所以只,所以只

要交换上述对应关系式中的要交换上述对应关系式中的 ii 和和 jj 即可得到:即可得到:

k=j*(j-1)/2+i-1 i<jk=j*(j-1)/2+i-1 i<j

22 、三角矩阵、三角矩阵

以主对角线划分,三角矩阵有以主对角线划分,三角矩阵有上三角上三角和和下三角下三角两种。两种。上三角矩阵如图所示,它的下三角(不包括主对角线)上三角矩阵如图所示,它的下三角(不包括主对角线)中的元素均为常数。下三角矩阵正好相反,它的主对中的元素均为常数。下三角矩阵正好相反,它的主对角线上方均为常数,如图所示。在大多数情况下,角线上方均为常数,如图所示。在大多数情况下,三角矩阵常数为零。三角矩阵常数为零。 a11 a12 … a 1 n a11 c … ca11 a12 … a 1 n a11 c … c c a22 … a 2 n a21 a22 … cc a22 … a 2 n a21 a22 … c ………………… ………………….. …………….... …………….. c c … a n n a n 1 a n 2 … a n c c … a n n a n 1 a n 2 … a n

n n (a)(a) 上三角矩阵 上三角矩阵 (b)(b) 下三角矩阵下三角矩阵

三角矩阵三角矩阵

三角矩阵存储三角矩阵存储

aa1,11,1 aa1,21,2 …… aa1,n1,n aa2,22,2 aa2,32,3 …… aa 2, n 2, n ………… aan,nn,n

对上三角阵只需存上三角部分,一维数组对上三角阵只需存上三角部分,一维数组 BB 中从中从 00 号位号位置开始存放,并按行优先存储,如下图所示:置开始存放,并按行优先存储,如下图所示:

0 1 … n-1 n n+1 … 2n-2 … 0 1 … n-1 n n+1 … 2n-2 … n(n+1)/2-1n(n+1)/2-1

则对矩阵则对矩阵 AA 的任意矩阵元素的任意矩阵元素 aaijij (( i≤ji≤j ),在按行优先存储的),在按行优先存储的情况下,它在一维数组情况下,它在一维数组 BB 中对应的存储位置为:中对应的存储位置为:

LOC(i,j)=n+(n-1)+(n-2)……+(n-(i-1)+1)+(j-i)LOC(i,j)=n+(n-1)+(n-2)……+(n-(i-1)+1)+(j-i)

=(2n-i+2)(i-1)/2+j-i=(2n-i+2)(i-1)/2+j-i

33 、对角矩阵、对角矩阵 (( 了解了解 )) 对角矩阵中,所有的非零元素集中在以主对对角矩阵中,所有的非零元素集中在以主对角线为中心的角线为中心的带状区域带状区域中,即除了主对角线和主中,即除了主对角线和主对角线相邻两侧的若干条对角线上的元素之外,对角线相邻两侧的若干条对角线上的元素之外,其余元素皆为零。下图给出了一个三对角矩阵,其余元素皆为零。下图给出了一个三对角矩阵,

aa0000 a a0101

aa1010 a a1111 a a1212

aa2121 a a2222 a a2323

… …. ….. …. . ….. …. aan-2 n-3n-2 n-3 a an-2 n-2n-2 n-2 a an-2 n-1n-2 n-1

aan-1 n-2n-1 n-2 a an-1 n-1n-1 n-1

对角矩阵可按行优先顺序或对角线的顺序,将对角矩阵可按行优先顺序或对角线的顺序,将其压缩存储到一个向量中,并且也能找到每个非其压缩存储到一个向量中,并且也能找到每个非零元素和向量下标的对应关系。零元素和向量下标的对应关系。

(0≤i≤n-1,i-1≤j ≤i+1) (0≤i≤n-1,i-1≤j ≤i+1) LOC(i,j)=2i+jLOC(i,j)=2i+j

5.3.2 5.3.2 稀疏矩阵稀疏矩阵

什么是什么是稀疏矩阵稀疏矩阵?简单说,矩阵?简单说,矩阵非零元素非零元素远远小于矩阵元素的总数远远小于矩阵元素的总数,则称为稀疏矩,则称为稀疏矩阵阵 ..

在存储稀疏矩阵时,为了节省存储单元,在存储稀疏矩阵时,为了节省存储单元,只存储非零元素。故用一个只存储非零元素。故用一个三元组三元组(i,j,a(i,j,aijij)) 来存储矩阵的一个非零元。来存储矩阵的一个非零元。

一个三元组一个三元组 (i,j,a(i,j,aijij)) 唯一确定了矩唯一确定了矩阵的一个非零元。因此,稀疏矩阵可由表阵的一个非零元。因此,稀疏矩阵可由表示非零元的示非零元的三元组三元组及其及其行列数行列数唯一确定。唯一确定。

例如,下列三元组表例如,下列三元组表

((1,2,12)(1,3,9),(3,1,- 3),(3,6,14),((1,2,12)(1,3,9),(3,1,- 3),(3,6,14),(4,3,24), (5,2,18),(6,1,15),(6,4,-7))(4,3,24), (5,2,18),(6,1,15),(6,4,-7))

加上加上 (6,7)(6,7) 这一对行、列值便可作为下列矩阵这一对行、列值便可作为下列矩阵 MM的另一种描述的另一种描述

0 12 9 0 0 0 00 12 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -3 0 0 0 0 14 0-3 0 0 0 0 14 0 0 0 24 0 0 0 00 0 24 0 0 0 0 0 18 0 0 0 0 00 18 0 0 0 0 0 15 0 0 –7 0 0 015 0 0 –7 0 0 0 稀疏矩阵稀疏矩阵 M M

而由上述三元组表的不同表示方法可引而由上述三元组表的不同表示方法可引出稀疏矩阵不同的压缩存储方法。出稀疏矩阵不同的压缩存储方法。

一、三元组顺序表(理解)一、三元组顺序表(理解)二、行逻辑链接的顺序表(了解)二、行逻辑链接的顺序表(了解)三、十字链表(了解)三、十字链表(了解)

一、三元组顺序表(以行为主的顺序)

0280036

00070

500140

ii jj vv

11 22 1414

11 55 -5-5

22 22 -7-7

33 11 3636

33 44 2828

三元组顺序表存储表示三元组顺序表存储表示 #define MAXSIZE 12500 //#define MAXSIZE 12500 // 非非 00 元个数最大值元个数最大值

typedef int ElemType; //typedef int ElemType; // 元素值类型元素值类型 typedef struct{typedef struct{ int i,j; //int i,j; // 非非 00 元的行列下标值元的行列下标值 ElemType e; ElemType e; }Triple; //}Triple; // 三元组类型三元组类型 typedef struct{typedef struct{

Triple data[MAXSIZE+1]; //data[0]Triple data[MAXSIZE+1]; //data[0]不用不用

int mu,nu,tu;//int mu,nu,tu;// 行数、列数、非行数、列数、非 00 元个数元个数 }TSMatrix; //}TSMatrix; // 三元组顺序表类型三元组顺序表类型

矩阵的转置运算矩阵的转置运算

普通矩阵的转置如何实现普通矩阵的转置如何实现 ??

aijaij 和和 ajiaji 互换互换 .. 算法实现思想算法实现思想 ??

在转置之前需要完成的任务在转置之前需要完成的任务 :: 矩阵信息矩阵信息存贮到在计算机中存贮到在计算机中 ,, 运用实际的存贮形式运用实际的存贮形式来完成转置任务来完成转置任务 ,, 结果需要显示给用户结果需要显示给用户 ..

矩阵的转置运算算法思想矩阵的转置运算算法思想 一个一个 m×nm×n 的矩阵的矩阵 AA ,它的转置,它的转置 BB 是一是一

个个 n×mn×m 的矩阵,且的矩阵,且 a[i][j]=b[j]a[i][j]=b[j][i][i] ,, 1≦i≦m1≦i≦m ,, 1≦j≦n1≦j≦n ,即,即 AA 的行是的行是 BB 的的列,列, AA 的列是的列是 BB 的行。的行。

将将 AA 转置为转置为 BB ,就是将,就是将 AA 的三元组表的三元组表a.dataa.data 置换为表置换为表 BB 的三元组表的三元组表 b.datab.data ,,如果只是如果只是简单地交换简单地交换 a.dataa.data 中中 ii 和和 jj 的内的内容,那么得到的容,那么得到的 b.datab.data 将是一个将是一个按列优先按列优先顺序存储的稀疏矩阵顺序存储的稀疏矩阵 BB ,要得到按,要得到按行优先行优先顺顺序存储的序存储的 b.datab.data ,就必须,就必须重新排列三元组重新排列三元组的顺序。的顺序。

例如: A=

0280036

00070

500140

ii jj vv

11 22 1414

11 55 -5-5

22 22 -7-7

33 11 3636

33 44 2828

0280

0

36

0

0

0-7 0

-500

140

ii jj vv

22 11 1414

55 11 -5-5

22 22 -7-7

11 33 3636

44 33 2828

B=

矩阵的转置运算算法思想矩阵的转置运算算法思想要得到转置结果要得到转置结果 ,, 结合转置前后三元组信息的特点结合转置前后三元组信息的特点 ,,

用用哪些哪些方法可以得到转置结果方法可以得到转置结果 ??

由于由于 AA 的列是的列是 BB 的行,因此,按的行,因此,按 a.dataa.data 的的列列序转置序转置 (( 先放第一列所有非先放第一列所有非 00 员,再放下一列所员,再放下一列所有非有非 00 元元 )) ,所得到的转置矩阵,所得到的转置矩阵 BB 的三元组表的三元组表b.datab.data 必定是必定是按行优先按行优先存放的。存放的。

两种方法:按照 b.data 中三元组的次序依次在 a.data 中找相应的三元组进行转置按照 a.data 中三元组的次序进行转置,并将转置后的三元组置入 b.data 中恰当位置

矩阵的转置矩阵的转置运算算法思想运算算法思想

对对 AA 中的中的每一列每一列 col(1≦col≦n)col(1≦col≦n) ,通过,通过从头从头至尾扫描至尾扫描三元表三元表 a.dataa.data ,找出,找出所有列号等于所有列号等于 colcol的那些三元组(的那些三元组( colcol 从从 11 依次递增到依次递增到 nn )),将它们,将它们的的行号和列号互换行号和列号互换后后依次放入依次放入 b.datab.data 中,即可得中,即可得到到 BB 的按行优先的压缩存储表示。的按行优先的压缩存储表示。

ii jj vv

11 22 1414

11 55 -5-5

22 22 -7-7

33 11 3636

33 44 2828

ii jj vv

11 33 3636

22 11 1414

22 22 -7-7

44 33 2828

55 11 -5-5

0280

0

36

0

0

0-7 0

-500

140

0280036

00070

500140

算法实现(理解算法,程序填空)算法实现(理解算法,程序填空) :p99:p99void TransposeSMatrix(TSMatrix M, TSMatrix &T)void TransposeSMatrix(TSMatrix M, TSMatrix &T){ T.mu=M.nu; { T.mu=M.nu; T.nu=M.mu; T.tu=M.tu; T.nu=M.mu; T.tu=M.tu; //// 行列互换行列互换 if(T.tu!=0) if(T.tu!=0) //// 非非 00 元个数不为元个数不为 00 则进行非则进行非 00 元素转置元素转置{ q=1; { q=1; //// 转置矩阵转置矩阵 TT 对应三元组中最新非对应三元组中最新非 00 元的位置元的位置

for(col=1;col<=M.nu;col++) for(col=1;col<=M.nu;col++) //// 按照按照 MM 的列进行扫描转置的列进行扫描转置 for(p=1;p<=M.tu;p++) for(p=1;p<=M.tu;p++) //// 对于每一行,都从三元组所有元素中扫描对于每一行,都从三元组所有元素中扫描 if(M.data[p].j==col) //if(M.data[p].j==col) //colcol 值比较值比较 ,, 该列出现一个非该列出现一个非 00 元,信息加元,信息加入入

{ T.data[q].i=M.data[p].j;{ T.data[q].i=M.data[p].j; T.data[q].j=M.data[p].i;T.data[q].j=M.data[p].i;

T.data[q].e=M.data[p].e; T.data[q].e=M.data[p].e; q++; q++; //q//q指向下一个位置指向下一个位置 } }

}}}}

算法分析算法分析

该算法主要的工作是在该算法主要的工作是在 pp 和和 colcol 的两个循环中的两个循环中完成的,故算法的时间复杂度为完成的,故算法的时间复杂度为 O(nu*tu)O(nu*tu) 。。而而一般传统矩阵的转置算法为:一般传统矩阵的转置算法为:

for(col=1;col<=nu;++col)for(col=1;col<=nu;++col)

for(row=1;row<=mu;++row)for(row=1;row<=mu;++row)

t[col][row]=m[row][col];t[col][row]=m[row][col];

其时间复杂度为其时间复杂度为 O(mu*nu)O(mu*nu) 。。当非零元素的个当非零元素的个数数 tutu 和和 mu*numu*nu 同数量级时,该算法的时间复杂同数量级时,该算法的时间复杂度为度为 O(mu*nuO(mu*nu22)) 。。因此,此算法仅适用于因此,此算法仅适用于tu<=mu*nutu<=mu*nu 的情况。的情况。

快速转置的算法快速转置的算法

设置两个一维数组设置两个一维数组 num[1..n]num[1..n] 和和 cpot[1..n]cpot[1..n] num[col]num[col] ::表示表示 MM 中第中第 colcol 列非零元素的个数列非零元素的个数 cpot[col]cpot[col] ::指示指示 MM 中第中第 colcol 列第一个非列第一个非 00 元的存元的存贮位置贮位置

显然有:显然有: cpot[1]=1cpot[1]=1 cpot[col]=cpot[col-1]+num[col-1] cpot[col]=cpot[col-1]+num[col-1] 2<=col<=a.nu2<=col<=a.nu

快速转置的算法快速转置的算法

算法思想:算法思想: 对对 AA 进行扫描,按进行扫描,按 AA 提供的提供的列号一次确定列号一次确定装装

入入 BB 的一个三元组的的一个三元组的位置位置。具体实施如下:。具体实施如下:一遍一遍扫描先确定三元组的扫描先确定三元组的位置关系位置关系,,二次扫描二次扫描由位置由位置关系关系装入三元组装入三元组。可见,。可见,位置关系是此种算法的位置关系是此种算法的关键关键。。

第一遍扫描第一遍扫描 AA 1.1. 确定确定 AA 的每一列即的每一列即 BB 的的每一行每一行的的元素个数元素个数,, 2.2. 确定确定 BB 每一行的第一个非每一行的第一个非 00 元应该存贮的位置 元应该存贮的位置 第二遍扫描:第二遍扫描:

对对 AA 进行扫描,对当前非进行扫描,对当前非 00 元进行定位和存贮。元进行定位和存贮。

快速转置的算法快速转置的算法 图图 5.5(P97)5.5(P97) 中的矩阵中的矩阵 MM 和相应的三元组和相应的三元组 AA 可以求得可以求得num[col]num[col] 和 和 cpot[col]cpot[col] 的值如下: 的值如下:

下面通过下面通过 numnum 和和 cpotcpot 数组值来观察几个非数组值来观察几个非 00 元的存入元的存入过程。过程。i j v 1 2 121 3 9 3 1 -3 3 6 14 4 3 24 5 2 18 6 1 15 6 4 -7

col 1 2 3 4 5 6 7 num[col] 2 2 2 1 0

1 0 cpot[col] 1 3 5 7 8 8 9i j v 1 3

-3 1 6

15 2 1

12 2 5

183 1 9 3 4

24 4 6

-7 6 3

14

1

2

3

46

Col 序号123456789

当对 A 扫描并将所有元素存入 B 后, B 的每行的位置与下一行的初始值重合

快速转置的算法实现(快速转置的算法实现( P10P1000 ))

void FastTransposeSMatrix(TSMatrix M, void FastTransposeSMatrix(TSMatrix M, TSMatrix &T)TSMatrix &T)

{{T.mu=M.nu; //T.mu=M.nu; // 行列互换行列互换

T.nu=M.mu;T.nu=M.mu; T.tu=M.tu;T.tu=M.tu; if(T.tu!=0)if(T.tu!=0)

{{ for(col=1;col<=M.nu;++col) //for(col=1;col<=M.nu;++col) // 设置设置 numnum初值初值 num[col]=0; num[col]=0;

////扫描第一遍扫描第一遍 MM 三元组信息,计算三元组信息,计算 numnum for(p=1;p<=M.tu;++p)for(p=1;p<=M.tu;++p)

num[M.data[p].j]++;num[M.data[p].j]++;

快速转置的算法实现(快速转置的算法实现( P10P1000 ))

cpot[1]=1; cpot[1]=1; //// 计算计算 cpotcpot 值值 for(p=2;p<=M.nu;p++)for(p=2;p<=M.nu;p++)

cpot[p]=cpot[p-1]+num[p-1];cpot[p]=cpot[p-1]+num[p-1]; //// 第二遍扫描第二遍扫描 MM 三元组,一次性定位和转置三元组,一次性定位和转置

for(p=1;p<=M.tu;++p) {for(p=1;p<=M.tu;++p) { col=M.data[p].j; col=M.data[p].j; ////取出该元素的列号取出该元素的列号

k=cpot[col]; k=cpot[col]; ////确定在确定在 TT 三元组中的应放位置三元组中的应放位置T.data[k].i=M.data[p].j; T.data[k].i=M.data[p].j; //// 放置信息放置信息

T.data[k].j=M.data[p].i;T.data[k].j=M.data[p].i; T.data[k].e=M.data[p].e;T.data[k].e=M.data[p].e;

cpot[col]++; cpot[col]++; //// 为该列出现的下一个非为该列出现的下一个非 00 元定位元定位 }} }}

}}

快速转置的算法快速转置的算法分析分析

11 、多用了两个辅助向量;、多用了两个辅助向量;22 、时间复杂度:、时间复杂度: OO (( nu+tunu+tu ););33 、当非零元素的个数、当非零元素的个数 tutu 和和 mu*numu*nu 同数同数

量级时,时间复杂度:量级时,时间复杂度: OO (( mu×numu×nu ))

三元组顺序表特点三元组顺序表特点 非零元在表中按非零元在表中按行序有序行序有序存储,因此存储,因此

便于进行便于进行依行顺序处理的 矩阵运算依行顺序处理的 矩阵运算;然而,;然而,若需若需按行号存取某一行的非零元按行号存取某一行的非零元,则需从,则需从头开始进行查找。另当矩阵的头开始进行查找。另当矩阵的非零元个数非零元个数和位置在操作过程中变化和位置在操作过程中变化较大时,就不适较大时,就不适宜了。宜了。

解决方法:解决方法:三元组采用其他表示方法三元组采用其他表示方法 行逻辑链接的顺序表行逻辑链接的顺序表和和十字链表十字链表

作业作业11 、设定二维整数数组、设定二维整数数组 B[0..m-1B[0..m-1 ,, 0..n-0..n-

1]1] 的数据在行、列方向上都按从小到大的的数据在行、列方向上都按从小到大的顺序排序,且整型变量顺序排序,且整型变量 xx 中的数据在中的数据在 BB 中中存在。试设计一个算法,找出一对满足存在。试设计一个算法,找出一对满足B[i][j]=xB[i][j]=x 的的 ii 、、 jj 值。要求比较次数不超值。要求比较次数不超过过 m+nm+n 。。

22 、编写一个算法,计算一个三元组表表示、编写一个算法,计算一个三元组表表示的稀疏矩阵的对角线元素之和。的稀疏矩阵的对角线元素之和。

第五章 数组和广义表第五章 数组和广义表5.1 5.1 数组的定义数组的定义5.2 5.2 数组的顺序表示和实现数组的顺序表示和实现5.3 5.3 矩阵的压缩存储矩阵的压缩存储 5.3.1 5.3.1 特殊矩阵特殊矩阵 5.3.2 5.3.2 稀疏矩阵稀疏矩阵5.4 5.4 广义表的定义及存储结构广义表的定义及存储结构

5.4 5.4 广义表广义表

11 、定义:、定义:广义表广义表(( ListsLists ,又称,又称列表列表))是线性表的推广是线性表的推广。。 广义表广义表是是 n(n>=0)n(n>=0) 个元素个元素 aa11,a,a22,a,a33,…,a,…,ann 的有的有限序列,其中限序列,其中 aaii 或者是或者是原子项原子项,或者是一个,或者是一个广义表广义表。通常记作。通常记作 LS=LS= (( aa11,a,a22,a,a33,,…,a…,ann)) 。。 LSLS 是广义表的名字,是广义表的名字, nn 为它的长度。为它的长度。若若 aaii 是广义表,则称它为是广义表,则称它为 LSLS 的子表。的子表。

广义表是递归定义的线性结构, LS = ( 1, 2, , n ) 其中: i 或为原子 或为广义表

例:(例:( 11 )) A=A= ()()(( 22 )) B=B= (( ee ))(3) C=(a,(b,c,d))(3) C=(a,(b,c,d))

(4) D=(A,B,C)(4) D=(A,B,C)

(5) E=(a,E)(5) E=(a,E)

习惯上,大写字母表示名称,小写字母表示原子。当广义表非空时,第一个元素称为表头,其余元素组成的表称为表尾。

例 (2) 的表头为 e ,表尾为()。例 (3) 的表头为 a ,表尾为(( b,c,d ))。

例 (4) 的表头为 A,表尾为( B,C )。

22 、广义表的特点、广义表的特点

列表是一个列表是一个多层次的结构多层次的结构;; 列表可为其他列表所列表可为其他列表所共享共享;; 列表可以是一个列表可以是一个递归的表递归的表递归表的深度是无穷值,长度是有限值。

33 、广义表的基本操作、广义表的基本操作(( 11 )求表长 ()求表长 ( 22 )求表深度)求表深度(( 33 )求表头 ()求表头 ( 44 )求表尾)求表尾

例如 : D = ( E, f ) = ((a, (b, c)) , f )

Length(D)=2 Head( D ) = E Tail( D ) = ( f )

Head( E ) = a Tail( E ) = ( ( b, c) ) Length(E)=2 Depth(E)=2

Head( (( b, c)) ) = ( b, c) Tail( (( b, c)) ) = ( ) Length( ((b,c)) )=1 Depth( ((b,c)) )=2

44 、广义表的存储结构、广义表的存储结构 由于广义表中的数据元素可以由于广义表中的数据元素可以具有不同具有不同

结构(原子或列表)结构(原子或列表),因此难以用顺序存,因此难以用顺序存储结构表示,通常储结构表示,通常用链式存储结构用链式存储结构,每个,每个数据元素可用一个结点表示。有两种结点数据元素可用一个结点表示。有两种结点结构:结构:原子原子和和列表列表。。

tag=tag=00

atomatom tag=1tag=1 hphp tptp

原子 列表

例如:例如: C=(a,(b,c,d))C=(a,(b,c,d))

00 aa

11C

11 ∧∧1111

11 ∧∧

00 cc00 bb 00 dd

55 、广义表的递归算法、广义表的递归算法 求广义表的深度求广义表的深度 复制广义表复制广义表 建立广义表的存储结构建立广义表的存储结构

求广义表的深度的递归算法求广义表的深度的递归算法

广义表广义表 LS=LS= (( aa11 ,, aa22 ,,…………,, aann ))的深度的深度DEPTHDEPTH (( LSLS )的递归定义为:)的递归定义为:

基本项:基本项: DEPTHDEPTH (( LSLS )) =1 =1 当当 LSLS 为空表时为空表时 DEPTHDEPTH (( LSLS )) =0 =0 当当 LSLS 为原子时为原子时归纳项:归纳项: DEPTHDEPTH (( LSLS )) =1+MAX{DEPTH=1+MAX{DEPTH (( aaii )) } }

n≥1n≥11≤i≤n

C=(a,(b,c,d))C=(a,(b,c,d))

本章小结本章小结

问题问题 11 :数组是一种逻辑结构还是物理结构?:数组是一种逻辑结构还是物理结构?问题问题 22 :数组的逻辑结构是什么?:数组的逻辑结构是什么?问题问题 33 :数组的基本操作有哪些?:数组的基本操作有哪些?问题问题 44 :矩阵可采用什么存储结构?矩阵的基本运算有:矩阵可采用什么存储结构?矩阵的基本运算有哪些?哪些?

问题问题 55 :广义表是线性结构还是非线性结构?为什么?:广义表是线性结构还是非线性结构?为什么?问题问题 66 :广义表有哪些特性?:广义表有哪些特性?问题问题 77 :广义表的基本操作有哪些?:广义表的基本操作有哪些?