第五章 数组和广义表
DESCRIPTION
第五章 数组和广义表. 本章内容 5.1 数组的定义 5.2 数组的顺序表示 5.3 矩阵的压缩存储 5.3.1 特殊矩阵 5.3.2 稀疏矩阵 5.4 广义表的定义 5.5 广义表的存储结构. 5.1 数组的定义. 数组是我们很熟悉的一种数据结构,它可以看作线性表的推广。数组作为一种数据结构其特点是 结构中的元素本身可以是具有某种结构的数据,但属于同一数据类型 ,比如:一维数组可以看作一个线性表,二维数组可以看作 “ 数据元素是一维数组 ” 的一维数组,三维数组可以看作 “ 数据元素是二维数组 ” 的一维数组,依此类推。. - PowerPoint PPT PresentationTRANSCRIPT
数据结构 – Data Structures
第五章 数组和广义表 本章内容
5.1 数组的定义5.2 数组的顺序表示5.3 矩阵的压缩存储 5.3.1 特殊矩阵 5.3.2 稀疏矩阵5.4 广义表的定义5.5 广义表的存储结构
数据结构 – Data Structures
5.1数组的定义 数组是我们很熟悉的一种数据结构,它可以看
作线性表的推广。数组作为一种数据结构其特点是结构中的元素本身可以是具有某种结构的数据,但属于同一数据类型,比如:一维数组可以看作一个线性表,二维数组可以看作“数据元素是一维数组”的一维数组,三维数组可以看作“数据元素是二维数组”的一维数组,依此类推。
由于数组中各元素具有统一的类型,并且数组元素的下标一般具有固定的上界和下界,因此,数组的处理比其它复杂的结构更为简单。多维数组是一维数组的推广。
数据结构 – Data Structures
例如,二维数组 A :
5.1数组的定义 ( 续 )
Am×n=
a11 a12 … a1n
a21 a22 … a2n
… … … …
am1 am2 … amn
二维数组 A 可以看成是由 m 个行向量组成的向量,也可以看成是 n 个列向量组成的向量。
数组一旦被定义,它的维数和维界就不再改变。因此,除了结构的初始化和销毁之外,数组只有存取元素和修改元素值的操作。
数据结构 – Data Structures
由于计算机的内存结构是一维的,因此用一维内存来表示多维数组,就必须按某种次序将数组元素排成一列序列,然后将这个线性序列存放在存储器中。
数组一旦建立,结构中的元素个数和元素间的关系就不再发生变化。因此,一般采用顺序存储的方法来表示数组。
5.2 数组的顺序表示
数据结构 – Data Structures
行优先顺序或以行为主序存储方式:将数组元素按行排列,第 i+1个行向量紧接在第 i 个行向量后面。以二维数组为例,按行优先顺序存储的线性序列为: a11,a12,…,a1n,a21,a22,…a2n,……,am1,am2,…,amn
在 PASCAL、 C 等语言中,数组就是按行优先顺序存储的。
5.2 数组的顺序表示 ( 续 )
Am×n=
a11 a12 … a1n
a21 a22 … a2n
… … … …
am1 am2 … amn
LOC(aij)=LOC(a11)+[(i-1)*n+j-1]*d
数据结构 – Data Structures
列优先顺序或以列为主序存储方式:将数组元素按列向量排列,第 j+1个列向量紧接在第 j 个列向量之后, A 的 m*n个元素按列优先顺序存储的线性序列为:
a11,a21,…,am1,a12,a22,…am2,……,an1,an2,…,anm
在 FORTRAN语言中,数组按列优先顺序存储。
5.2 数组的顺序表示 ( 续 )
Am×n=
a11 a12 … a1n
a21 a22 … a2n
… … … …
am1 am2 … amn
LOC(aij)=LOC(a11)+[(j-1)*m+i-1]*d
数据结构 – Data Structures
行优先顺序——先排最右的下标,从右到左,最后排最左下标。
列优先顺序——先排最左下标,从右向左,最后排最左下标。
例如:三维数组 Am*n*p
5.2 数组的顺序表示 ( 续 )
数据结构 – Data Structures
只要知道开始结点的存放地址(即基地址)、维数和每维的上、下界,以及每个数组元素所占用的单元数,就可以将数组元素的存放地址表示为其下标的线性函数。因此,数组中的任一元素可以在相同的时间内存取,即顺序存储的数组是一个随机存取结构。
数组存储的特点
Example
数据结构 – Data Structures
压缩存储:为多个值相同的非零元素只分配一个存储空间;对零元素不分配空间。
5.3 矩阵的压缩存储
数据结构 – Data Structures
特殊矩阵:非零元素按照一定的规律分布。
5.3.1特殊矩阵的压缩存储
a1,1 a1,2 … a1,n
a2,1 a2,2 … a2,n
… … ai,j …
an,1 an,2 … an,n
aij=aji
1 2 3 4
2 1 3 4
3 3 1 4
4 4 4 1
对称矩阵
常见的特殊矩阵有对称矩阵、三角矩阵、对角矩阵等。 对称矩阵:元素的值按照主对角线对称
数据结构 – Data Structures
5.3.1( 续 )对称矩阵的压缩存储
对称矩阵
1 2 3 4
2 1 3 4
3 3 1 4
4 4 4 1
1 2 3 4
2 1 3 4
3 3 1 4
4 4 4 1
1 2 1 3 3 1 4 4 4 1数组 B1 2 3 4 5 6 7 8 9 10下标 k
例如:一个 4*4的对称矩阵。
数据结构 – Data Structures
5.3.1( 续 )对称矩阵的压缩存储
对称矩阵
数组 B ai,j an,na1,1 a2,1 a2,2 a3,1
1 2 3 4 k m下标
a1,1 a1,2 … a1,n
a2,1 a2,2 … a2,n
… … ai,j …
an,1 an,2 … an,n
a1,1
a2,1 a2,2
… ai,j …
an,1 an,2 … an,n
… … k = ?
m = ?
推广至一般情况, n*n的对称矩阵
数据结构 – Data Structures
5.3.1( 续 )三角矩阵的压缩存储
1 0 0 0
2 1 0 0
3 3 1 0
4 4 4 1
1 2 3 4
0 1 3 4
0 0 1 4
0 0 0 1
(a) 下三角矩阵
(a) 上三角矩阵
三角矩阵:上 ( 下 ) 三角矩阵是指矩阵的下(上)三角(不包括对角线)中的元素均为常数或零的 n 阶矩阵,即非零元素的分布在矩阵中呈现为三角形。
例如:一个 4*4的三角矩阵。
数据结构 – Data Structures
5.3.1( 续 )三角矩阵的压缩存储
1 8 8 8
2 1 8 8
3 3 1 8
4 4 4 1
1 2 3 4
9 1 3 4
9 9 1 4
9 9 9 1
(c) 下三角矩阵 (d) 上三角矩阵
例如:一个 4*4的三角矩阵。
数据结构 – Data Structures
5.3.1( 续 )三角矩阵的压缩存储
a0,0 a0,1 a0,2 … … … a0,n-2 a0, n-
1
a1,1 a1,2 … … … a1,n-2 a1, n-
1
… … … ai,i … ai,j … ai, n-
1
… … … an-1, n-
1
0
a0,0
a0,1
a0,2
a0,3
ai,j
an-1, n-1
b1
b2
b3
b4
bk
bm
… …
… …
k = ? m = ?
推广至一般情况, n*n的三角矩阵以行为主序压缩存储
数据结构 – Data Structures
5.3.1( 续 )三角矩阵的压缩存储
a0,0 a0,1 a0,2 … … … a0,n-2 a0, n-
1
a1,1 a1,2 … … … a1,n-2 a1, n-
1
… … … ai,i … ai,j … ai, n-
1
… … … an-1, n-
1
0
a0,0
a0,1
a1,1
a0,2
ai,j
an-1, n-1
b1
b2
b3
b4
bk
bm
… …
… … k = ? m = ?
a1,2 b5
a2,2 b6
推广至一般情况, n*n的三角矩阵以列为主序压缩存储
数据结构 – Data Structures
5.3.1( 续 )三对角矩阵的压缩存储
a0,0 a0,1
a1,0 a1,1 a1,2
a2,1 a2,2 a2,3
…. ai,j …. an-2,n-3 an-2,n-2 an-2,n-1
an-1,n-2 an-1, n-
1
a0,0 a0,1 a1,0 ai,j数组 B
1 2 k k+1 m下标 0
... ...
k = ?
m = ?
对角矩阵是指所有的非零元素都集中在以主对角线为中心的带状区域中。
数据结构 – Data Structures
上述各种特殊矩阵,其非零元素的分布都是有规律的,因此总能找到一种方法将它们压缩存储到一维数组中,并且一般都能找到矩阵中的元素与该一维数组元素的对应关系,通过这个关系,仍能对矩阵的元素进行随机存取。
5.3.1( 续 )特殊矩阵的压缩存储
Example
数据结构 – Data Structures
什么是稀疏矩阵?简单说,设矩阵 A 中有 s个非零元素,若 s 远远小于矩阵元素的总数(即 s≦m×n),则称 A 为稀疏矩阵。
设在矩阵 A 中,有 s 个非零元素。令 e=s/(m*n),称 e 为矩阵的稀疏因子。通常认为 e≦0.05时称之为稀疏矩阵。
5.3.2稀疏矩阵
数据结构 – Data Structures
5.3.2稀疏矩阵的压缩存储
在存储稀疏矩阵时,由于非零元素的分布一般是没有规律的,因此在存储非零元素的同时,还必须同时记下它所在的行和列的位置( i,j)。反之,一个三元组 (i,j,aij) 惟一确定了矩阵A 的一个非零元。因此,稀疏矩阵可由表示非零元的三元组及其行列数唯一确定。
数据结构 – Data Structures
( (1,2,12), (1,3,9), (3,1,-3), (3,6,14), (4,3,24), (5,2,18), (6,1,15), (6,4,-7) )
5.3.2稀疏矩阵的压缩存储
M=
0 12 9 0 0 0 0 0 0 0 0 0 0 0-3 0 0 0 0 14 0 0 0 24 0 0 0 0 0 18 0 0 0 0 015 0 0 –7 0 0 0
例如,一个 6*7的稀疏矩阵
稀疏矩阵中的非零元素
数据结构 – Data Structures
假设以顺序存储结构来表示三元组表,则可得到稀疏矩阵的一种压缩存储方法——三元组顺序表。
#define maxsize 10000 typedef int datatype; typedef struct{ int i,j; datatype v; }triple; /* 三元组 */
5.3.2( 续 )稀疏矩阵的压缩存储
数据结构 – Data Structures
typedef struct{ triple
data[maxsize]; int m,n,t; }tripletable;
5.3.2( 续 )三元组顺序表
M=
0 12 9 0 0 0 0 0 0 0 0 0 0 0-3 0 0 0 0 14 0 0 0 24 0 0 0 0 0 18 0 0 0 0 015 0 0 –7 0 0 0
i j v
1 2 12
1 3 9
3 1 -3
3 6 14
4 3 24
5 2 18
6 1 15
6 4 -7
12
34
56
78
转置
MT=
0 0 -3 0 0 1512 0 0 0 18 0 9 0 0 24 0 0 0 0 0 0 0 -7 0 0 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0
M=
0 12 9 0 0 0 0 0 0 0 0 0 0 0-3 0 0 0 0 14 0 0 0 24 0 0 0 0 0 18 0 0 0 0 015 0 0 –7 0 0 0
数据结构 – Data Structures
5.3.2( 续 )三元组顺序表上的转置
i j v 1 2 12 1 3 9 3 1 -3 3 6 14 4 3 24 5 2 18 6 1 15 6 4 -7
12
34
56
7
0
转置
i j v 2 1 12 3 1 9 1 3 -3 6 3 14 3 4 24 2 5 18 1 6 15 4 6 -7
12
34
56
7
0
排序
i j v 1 3 -3 1 6 15 2 1 12 2 5 18 3 1 9 3 4 24 4 6 -7 6 3 14
12
34
56
7
0
数据结构 – Data Structures
typedef struct{ triple
data[maxsize]; int m,n,t;}tripletable;
Void transmatrix(tripletable A, tripletable &AT) {
AT.m=A.n; AT.n=A.m; AT.t=A.t;
if (AT.t<=0) return;
for(p=0;p<A.t;++p) {
AT.data[p].i = AT.data[p].j; AT.data[p].j = AT.data[p].i;
AT.data[p].v = AT.data[p].v;
}
// 按照 AT.data[p].i 进行非递减排序
}
5.3.2( 续 )三元组顺序表
数据结构 – Data Structures 5.3.2( 续 )三元组顺序表上的转置( 二 )
转置
i j v 1 2 12 1 3 9 3 1 -3 3 6 14 4 3 24 5 2 18 6 1 15 6 4 -7
12
34
56
7
0
i j v 1 3 -3 1 6 15 2 1 12 2 5 18 3 1 9 3 4 24 4 6 -7 6 3 14
12
34
56
7
0
数据结构 – Data Structures
设置向量 num,num[col]表示矩阵 A 中第col列中非零元的个数。 (A 的列数:A.n)
5.3.2( 续 )三元组顺序表上的转置( 二 )
for(col=1;col<=A.n;++col) num[col] = 0;
for(p=1;p<=A.t;++p) // 计算 A 中每列非零元的个数
num[A.data[p].j]++;列号
数据结构 – Data Structures
设置向量 cpot,cpot[col]指示 A 中第col列的第一个非零元在转置矩阵 AT.data中的恰当位置。
5.3.2( 续 )三元组顺序表上的转置 ( 二 )
cpot[1]=1cpot[col]=cpot[col-1]+num[col-1]
2≤col≤A.n
cpot[1]=1;for(col = 2; col<=A.n; ++col) cpot[col]=cpot[col-1]+num[col-1];
数据结构 – Data Structures 5.3.2( 续 )三元组顺序表上的转置( 二 )
cpot
1 3 5 7 8 8 9 1 2 3 4 5 6 7
num 2 2 2 1 0 1 0
M=
0 12 9 0 0 0 0 0 0 0 0 0 0 0-3 0 0 0 0 14 0 0 0 24 0 0 0 0 0 18 0 0 0 0 015 0 0 –7 0 0 0
数据结构 – Data Structures
转置
i j v 1 2 12 1 3 9 3 1 -3 3 6 14 4 3 24 5 2 18 6 1 15 6 4 -7
23
45
67
8
1
i j v
23
45
67
8
1
cpot
1 3 5 7 8 8 9 1 2 3 4 5 6 7
2 1 12
三元组顺序表上的转置 ( 二续 )
数据结构 – Data Structures
转置
i j v 1 2 12 1 3 9 3 1 -3 3 6 14 4 3 24 5 2 18 6 1 15 6 4 -7
23
45
67
8
1
i j v
23
45
67
8
1
cpot
1 4 5 7 8 8 9 1 2 3 4 5 6 7
2 1 12
三元组顺序表上的转置 ( 二续 )
数据结构 – Data Structures
转置
i j v 1 2 12 1 3 9 3 1 -3 3 6 14 4 3 24 5 2 18 6 1 15 6 4 -7
23
45
67
8
1
i j v
23
45
67
8
1
cpot
1 4 5 7 8 8 9 1 2 3 4 5 6 7
2 1 12
3 1 9
三元组顺序表上的转置 ( 二续 )
数据结构 – Data Structures
转置
i j v 1 2 12 1 3 9 3 1 -3 3 6 14 4 3 24 5 2 18 6 1 15 6 4 -7
23
45
67
8
1
i j v
23
45
67
8
1
cpot
1 4 6 7 8 8 9 1 2 3 4 5 6 7
2 1 12
3 1 9
三元组顺序表上的转置 ( 二续 )
数据结构 – Data Structures
转置
i j v 1 2 12 1 3 9 3 1 -3 3 6 14 4 3 24 5 2 18 6 1 15 6 4 -7
23
45
67
8
1
i j v
23
45
67
8
1
cpot
1 4 6 7 8 8 9 1 2 3 4 5 6 7
2 1 12
3 1 9
1 3 -3
三元组顺序表上的转置 ( 二续 )
数据结构 – Data Structures
转置
i j v 1 2 12 1 3 9 3 1 -3 3 6 14 4 3 24 5 2 18 6 1 15 6 4 -7
23
45
67
8
1
i j v
23
45
67
8
1
cpot
2 4 6 7 8 8 9 1 2 3 4 5 6 7
2 1 12
3 1 9
6 3 14
1 3 -3
三元组顺序表上的转置 ( 二续 )
数据结构 – Data Structures
转置
i j v 1 2 12 1 3 9 3 1 -3 3 6 14 4 3 24 5 2 18 6 1 15 6 4 -7
23
45
67
8
1
i j v
23
45
67
8
1
cpot
2 4 6 7 8 9 9 1 2 3 4 5 6 7
2 1 12
3 1 9
3 4 24
1 3 -3
6 3 14
三元组顺序表上的转置 ( 二续 )
数据结构 – Data Structures
转置
i j v 1 2 12 1 3 9 3 1 -3 3 6 14 4 3 24 5 2 18 6 1 15 6 4 -7
23
45
67
8
1
i j v
23
45
67
8
1
cpot
2 4 7 7 8 9 9 1 2 3 4 5 6 7
2 1 12
3 1 92 5 18
1 3 -3
6 3 14
3 4 24
三元组顺序表上的转置 ( 二续 )
数据结构 – Data Structures
转置
i j v 1 2 12 1 3 9 3 1 -3 3 6 14 4 3 24 5 2 18 6 1 15 6 4 -7
23
45
67
8
1
i j v
23
45
67
8
1
cpot
2 5 7 7 8 9 9 1 2 3 4 5 6 7
2 1 12
3 1 9
1 6 15
1 3 -3
6 3 14
3 4 24
2 5 18
三元组顺序表上的转置 ( 二续 )
数据结构 – Data Structures
转置
i j v 1 2 12 1 3 9 3 1 -3 3 6 14 4 3 24 5 2 18 6 1 15 6 4 -7
23
45
67
8
1
i j v
23
45
67
8
1
cpot
3 5 7 7 8 9 9 1 2 3 4 5 6 7
2 1 12
3 1 9
4 6 -7
1 3 -3
6 3 14
3 4 24
2 5 18
1 6 15
三元组顺序表上的转置 ( 二续 )
数据结构 – Data Structures
for(col=1;col<=A.n;++col) num[col] = 0;for(p=1;p<=A.t;++p) // 计算 A 中每列非零元的个数 num[A.data[p].j]++;
5.3.2( 续 )三元组顺序表上的转置( 二 )
cpot[1]=1;for(col = 2; col<=A.n; ++col) // 计算元素位置 cpot[col]=cpot[col-1]+num[col-1];
for(col=1;col<=A.n;++col) num[col] = 0;for(p=1;p<=A.t;++p) // 计算 A 中每列非零元的个数 num[A.data[p].j]++;
cpot[1]=1;for(col = 2; col<=A.n; ++col) // 计算元素位置 cpot[col]=cpot[col-1]+num[col-1];
for(p = 1; p<=A.t; ++p) {// 转置 col = A.data[p].j; q = cpot[col]; AT.data[q].i = A.data[p].j; AT.data[q].j = A.data[p].i; AT.data[q].v = A.data[p].v; cpot[col]++;}
十字链表
1 2 12 1 3 9
3 1 -3 3∧
6∧14
4 3 24
5 2 18
6 1 15 6 4 -7
∧
∧ ∧
∧ ∧
∧ ∧
∧
∧ ∧
∧
数据结构 – Data Structures
5.3广义表的定义 广义表是线性表的推广。
L=(a1,a2,...,an ),n≥0,ai 可以是单元素,也可以是一个表。 例如:
A = () B = (e) C = (a,(b,c,d)) D = (A,B,C) E = (a,E)
广义表的长度 广义表的深度 非空广义表
表头 (Head) :第一个元素 表尾 (Tail) :除第一个元素外其余元素构成的表
Example
数据结构 – Data Structures
广义表的存储结构 ( 一 ) 链表存储
C = (a,(b,c,d)) D = (A,B,C) E = (a,E)
链表结点结构
tag=1 hp tp
表结点
tag=0 atom
原子结点
数据结构 – Data Structures
广义表的存储结构 ( 一 )
C = (a,(b,c,d))
C 1
0 a
Head(C) = a Tail(C)=((b,c,d))
1
数据结构 – Data Structures
广义表的存储结构 ( 一 )
C = (a,(b,c,d))
C 1
0 a
1 ∧
Head(C) = a Tail(C)=((b,c,d))
1
(b,c,d)
数据结构 – Data Structures
广义表的存储结构 ( 一 )
C = (a,(b,c,d))
C 1
0 a
1 ∧
1
0 b
1
0 c
1 ∧
0 d
Head(C) = a Tail(C)=((b,c,d))
(b,c,d)
(c,d)
(d)
数据结构 – Data Structures
广义表的存储结构 ( 一 )
C = (a,(b,c,d))
C 1
0 a
1 ∧
1
0 b
1
0 c
1 ∧
0 d
B= (e)
C 1
0 a
1 ∧
1
0 b
1
0 c
1 ∧
0 d
1 ∧
0 e
B
数据结构 – Data Structures
A= ()
C 1
0 a
1 ∧
1
0 b
1
0 c
1 ∧
0 d
1 ∧
0 e
B
A ∧
D= (A,B,C)
C 1
0 a
1 ∧
1
0 b
1
0 c
1 ∧
0 d
1 ∧
0 e
B
A ∧
D 1 ∧ 1
(B,C)
1 ∧
(C)
数据结构 – Data Structures
5.4广义表的存储结构 ( 一 )
链表结点结构 tag=1 hp tp
表结点
tag=0 atom
原子结点typedef enum {ATOM,LIST} ElemTag;Typedef struct GLNode{ ElemTag tag; union { AtomType actom; struct {struct GLNode *hp,*tp;} ptr; };}*Glist;
数据结构 – Data Structures
5.4广义表的存储结构 ( 二 )
结点结构 tag=1 hp tp
表结点typedef enum {ATOM,LIST} ElemTag;typedef struct GLNode{ ElemTag tag; union { AtomType actom; struct GLNode *hp; }; struct GLNode *tp;}*Glist;
tag=0 atom
原子结点
tp
数据结构 – Data Structures
5.4广义表的存储结构 ( 二 )
C = (a,(b,c,d))
tag=1 hp tp
表结点
tag=0 atom
原子结点
tp
C 1 ∧
0 c 0 d ∧
0 a 1 ∧
0 b
数据结构 – Data Structures
5.4广义表的应用 m元多项式的表示P(x,y,z) = x10y3z2+2x6y3z2+3x5y2z2+x4y4z+6x3y4z+2yz+15 =(x10y3 +2x6y3 +3x5y2) z2 +(x4y4+6x3y4+2y)z+15 =A z2 +B z +15A(x,y) = x10y3 +2x6y3 +3x5y2
= (x10+2x6)y3 +3x5y2
= C y3 +Dy2
B(x,y) = x4y4+6x3y4+2y
= (x4+6x3)y4+2y
= Ey4+Fy
C(x) = x10+2x6
D(x) = 3x5
E(x) = x4+6x3
F(x) = 2
数据结构 – Data Structures
一个函数式程序
(DEFINE (factorial n)
(IF (= n 0)
1
(* n (factorial (- n 1)))
))
)1(*
1)(
nfactnnfact
0
0
n
n
数据结构 – Data Structures
本章小结 本章应掌握的内容
数组的按行存储和按列存储 特殊矩阵的压缩存储 广义表的定义、基本运算 ( 求表头、表尾 ) 广义表的存储结构
作业 5.1(3)(4) 5.2(3) 5.5 5.7 5.10(5)(7) 5.13(1) 5.18 5.23*