4.1 数组的定义

39
4.1 数数数数数 4.3 数数数数数数数数数 4.2 数数数数数数数数数数 4.4 数数数数数数 4.5 数数数数数数数数 数数数 数数数数数数

description

第四章 数组和广义表. 4.1 数组的定义. 4.2 数组的顺序表示和实现. 4.3 稀疏矩阵的压缩存储. 4.4 广义表的定义. 4.5 广义表的存储结构. 学习目标. 掌握数组的定义 熟悉数组的顺序表示和实现 掌握稀疏矩阵的压缩存储 掌握广义表的定义和存储结构. 4.1 数组的定义. ADT Array { 数据对象 : D = {a j1,j2, ...,,ji,jn | j i =0,...,b i -1, i=1,2,..,n } 数据关系 : R = {R1, R2, ..., Rn} - PowerPoint PPT Presentation

Transcript of 4.1 数组的定义

Page 1: 4.1   数组的定义

4.1 数组的定义

4.3 稀疏矩阵的压缩存储

4.2 数组的顺序表示和实现

4.4 广义表的定义

4.5 广义表的存储结构

第四章 数组和广义表

Page 2: 4.1   数组的定义

学习目标

掌握数组的定义 熟悉数组的顺序表示和实现 掌握稀疏矩阵的压缩存储 掌握广义表的定义和存储结构

Page 3: 4.1   数组的定义

4.1 数组的定义ADT Array {

数据对象: D = {aj1,j2, ...,,ji,jn| ji =0,...,bi -1, i=1,2,..,n }

数据关系: 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, i=2,...,n }

} ADT Array

基本操作 :

Page 4: 4.1   数组的定义

二维数组的定义 :

数据对象 : D = {aij | 0≤i≤b1-1, 0 ≤j≤b2-1}

数据关系 : R = { ROW, COL }

ROW = {<ai,j,ai+1,j>| 0≤i≤b1-2, 0≤j≤b2-1}

COL = {<ai,j,ai,j+1>| 0≤i≤b1-1, 0≤ j≤b2-2}

Page 5: 4.1   数组的定义

基本操作:

InitArray(&A, n, bound1, ..., boundn)

DestroyArray(&A)

Value(A, &e, index1, ..., indexn)

Assign(&A, e, index1, ..., indexn)

Page 6: 4.1   数组的定义

4.2 数组的顺序表示和实现

类型特点 :1) 只有引用型操作,没有加工型操作;2) 数组是多维的结构,而存储空间是 一个一维的结构。

有两种顺序映象的方式 :1) 以行序为主序 (低下标优先 );2) 以列序为主序 (高下标优先 )。

Page 7: 4.1   数组的定义

例如:

称为基地址或基址。

以“行序为主序”的存储映象

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

a0,1a0,0 a0,2

a1,0 a1,1 a1,2

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

L

L

Page 8: 4.1   数组的定义

推广到一般情况,可得到 n 维数组数据元素存储位置的映象关系

称为 n 维数组的映象函数。数组元素的存储位置是其下标的线性函数。

其中 cn = L , ci-1 = bi ×ci , 1 < i n 。

LOC(j1, j2, ..., jn ) = LOC(0,0,...,0) + ∑ ci ji i =1

n

Page 9: 4.1   数组的定义

4.3 矩阵的压缩存储 何谓压缩存储? 假若值相同的元素或者零元素在矩阵中的分布有一定

规律,则我们称此类矩阵为特殊矩阵,反之,称之为稀疏矩阵。

Page 10: 4.1   数组的定义

4.3.1 特殊矩阵

1 、对称矩阵 在一个 n阶方阵 A中,若元素满足下述性质: aij=aji 0≦i,j≦n-1则称 A为对称矩阵。

1 5 1 3 7 a00 5 0 8 0 0 a10 a 11 1 8 9 2 6 a20 a21 a23 3 0 2 5 1 ……………….. 7 0 6 1 3 an-1 0 a n-1 1 a n-1 2 …a n-1 n-1

Page 11: 4.1   数组的定义

存在对应关系: k=i*(i+1)/2+j 当 i≧j k=j*(j+1)/2+i 当 i<j 令 I=max(i,j) , J=min(i,j) ,则 k和 i, j的对应关系可统一为: k=I*(I+1)/2+J 0≦ k<n(n+1)/2

Page 12: 4.1   数组的定义

aij 的地址可用下列式计算: LOC(aij)=LOC(sa[k])

=LOC(sa[0])+k*d=LOC(sa[0]+[I*(I+1)/2+J]*d

由此,称 sa[n(n+1)/2] 为阶对称矩阵 A 的压缩存储

k=0 1 2 3 n(n-1)/2 n(n-1)/2-1例如 a21 和 a12 均存储在 sa[4] 中,这是因为 k=I*(I+1)/2+J=2*(2+1)/2+1=4

a00 a10 a11 a20 …… an-1 0 …… an-1,n-1

Page 13: 4.1   数组的定义

2 、三角矩阵

a00 a01 … a 0 n-1 a00 c … c

c a11 … a 1 n-1 a10 a11 … c

………………….. ……………..

c c … a n-1 n-1 an-1 0 an-1 1 … an-1 n-1

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

Page 14: 4.1   数组的定义

上三角矩阵sa[k]和aij的对应关系是: i(2n-i+1)/2+j-i 当i≦j n(n+1)/2 当i>j

下三角矩阵sa[k]和aij对应关系是: i(i+1)/2+j i≧j n(n+1)/2 i>j

k=

k=

Page 15: 4.1   数组的定义

3、对角矩阵

a00 a01

a10 a11 a12

a21 a22 a23

…. ….. …. 图 对角矩阵 an-2 n-3 an-2 n-2 an-2 n-1

an-1 n-2 an-1 n-1

Page 16: 4.1   数组的定义

需存储的元素个数为 3n-2

a00 a01 a10 a11 a12 a21 …… a n-1 n-2 a n-1 n-1

K=0 1 2 3 4 5 … … 3n-2 3n-1

非零元素 aij 的地址为: LOC(i,j)=LOC(0,0)+[3*i-1+(j-i+1)]*d =LOC(0,0)+(2i+j)*d 由此,我们称 sa[0..3*n-2] 是阶三对角带状矩阵A 的压缩存储表示。

Page 17: 4.1   数组的定义

假设 m 行 n 列的矩阵含 t 个非零元素,则称

为稀疏因子。通常认为 0.05 的矩阵为稀疏矩阵。

nmt

4.3.2 稀疏矩阵

何谓稀疏矩阵?

Page 18: 4.1   数组的定义

例如,下列三元组表((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) 这一对行、列值便可作为下列矩阵 M的另一种描述。

0 12 9 0 0 0 0 0 0 -3 0 0 15 0 0 0 0 0 0 0 12 0 0 0 18 0 -3 0 0 0 0 14 0 9 0 0 24 0 0 0 0 24 0 0 0 0 0 0 0 0 0 –7 0 18 0 0 0 0 0 0 0 14 0 0 0 15 0 0 –7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 图 稀疏矩阵 M和 T

M=T=

Page 19: 4.1   数组的定义

稀疏矩阵的压缩存储方法 :

一、三元组顺序表

二、行逻辑链接的顺序表

三、 十字链表

Page 20: 4.1   数组的定义

#define MAXSIZE 12500

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

一、三元组顺序表

typedef union { Triple data[MAXSIZE + 1]; int mu, nu, tu; } TSMatrix; // 稀疏矩阵类型

Page 21: 4.1   数组的定义

如何求转置矩阵?

0280036

00070

500140

005

2800

000

0714

3600

Page 22: 4.1   数组的定义

用“三元组”表示时如何实现?

1 2 14

1 5 -5

2 2 -73 1 363 4 28

2 1 14

5 1 -5

2 2 -7

1 3 36

4 3 28

Page 23: 4.1   数组的定义

Void transmatrix(tripletable a,tripletable b)

{

int p q col;

b.m=a.n;

b.n=a.m;

b.t=a.t;

if(b.t<=0)

printf(“A=0\n”);

q=0;

Page 24: 4.1   数组的定义

for(col=1;col<=a.n;col++)

for(p=0;p<=a.t;p++)

if(a.data[p].j==col){

b.data[q].i=a.data[p].j;

b.data[q].j=a.data[p].i;

b.data[q].v=a.data[p].v;

q++;

}

}

算法的时间复杂度为 O(n*n2)

Page 25: 4.1   数组的定义

三元组顺序表又称有序的双下标法,它的特点是,

非零元在表中按行序有序存储,因此便于进行依行顺序处理的矩阵运算。然而,若需随机存取某一行中的非零元,则需从头开始进行查找。

二、行逻辑链接的顺序表

Page 26: 4.1   数组的定义

三、 十字链表M.chead

M.rhead

3 0 0 50 -1 0 02 0 0 0

1 1 3 1 4 5

2 2 -1

3 1 2

^

^^

^ ^

^ ^

Page 27: 4.1   数组的定义

4.4 广义表的定义

ADT Glist {

数据对象: D = {ei | i=1,2,..,n; n≥0;

ei AtomSet ∈ 或 ei GList,∈ AtomSet 为某个数据对象 }

数据关系:

LR = {<ei-1, ei >| ei-1 ,ei D, 2≤i≤n}∈

} ADT Glist

基本操作 :

Page 28: 4.1   数组的定义

广义表是递归定义的线性结构,

LS = ( 1, 2, , n )

其中: i 或为原子 或为广义表

例如 : A = ( )

F = (d, (e))

D = ((a,(b,c)), F)

C = (A, D, F)

B = (a, B) = (a, (a, (a, , ) ) )

Page 29: 4.1   数组的定义

广义表是一个多层次的线性结构

例如:

D=(E, F)

其中 : E=(a, (b, c))

F=(d, (e))

D

E F

a ( ) d ( )

b c e

Page 30: 4.1   数组的定义

广义表 LS = ( 1, 2, …, n ) 的结构特点 :

1) 广义表中的数据元素有相对次序;

2) 广义表的长度定义为最外层包含元素个数;

3) 广义表的深度定义为所含括弧的重数; 注意:“原子”的深度为 0

 “空表”的深度为 1 4) 广义表可以共享;

5) 广义表可以是一个递归的表。 递归表的深度是无穷值,长度是有限值。

Page 31: 4.1   数组的定义

6) 任何一个非空广义表 LS = ( 1, 2, …, n) 均可分解为 表头 Head(LS) = 1 和 表尾 Tail(LS) = ( 2, …, n) 两部分。

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

Head( D ) = E Tail( D ) = ( F )

Head( E ) = a Tail( E ) = ( ( b, c) )

Head( (( b, c)) ) = ( b, c) Tail( (( b, c)) ) = ( )

Head( ( b, c) ) = b Tail( ( b, c) ) = ( c )

Head( ( c ) ) = c Tail( ( c ) ) = ( )

Page 32: 4.1   数组的定义

结构的创建和销毁 InitGList(&L); DestroyGList(&L); CreateGList(&L, S); CopyGList(&T, L);

基本操

状态函数 GListLength(L); GListDepth(L); GListEmpty(L); GetHead(L); GetTail(L);

插入和删除操作 InsertFirst_GL(&L, e); DeleteFirst_GL(&L, &e);

遍历 Traverse_GL(L, Visit());

Page 33: 4.1   数组的定义

4.5 广义表的存储结构

通常采用头、尾指针的链表结构

表结点 :

原子结点:

tag=1 hp tp

tag=0 data

Page 34: 4.1   数组的定义

1) 表头、表尾分析法:

构造存储结构的两种分析方法 :

若表头为原子,则为

空表 ls=NIL

非空表 lstag=1

指向表头的指针

指向表尾的指针

tag=0 data

否则,依次类推。

Page 35: 4.1   数组的定义

例如:

L=(a, (x, y), ((x)) )

a ((x, y), ((x)) )

(x, y) ( ((x)) )

x (y) ((x)) ( )

y ( ) (x) ( )

x ( )

Page 36: 4.1   数组的定义

L = ( a, ( x, y ), ( ( x ) ) )a ( x, y ) ( )

1 L

L = ( )

0 a

1 1

1 1

1

0 a

( )x

Page 37: 4.1   数组的定义

2) 子表分析法:

若子表为原子,则为

空表 ls=NIL

非空表

1

指向子表 1 的指针

tag=0 data

否则,依次类推。

1

指向子表 2 的指针

1

指向子表 n 的指针

ls …

Page 38: 4.1   数组的定义

例如 :

a (x, y) ((x))

LS=( a, (x,y), ((x)) )

ls

Page 39: 4.1   数组的定义

本章小结

本章介绍栈和队列的逻辑结构定义及在两种存储结构上如何实现栈和队列的基本运算。掌握栈和队列的特点的基础上,懂得在什么样的情况下能够使用栈和队列。掌握栈和队列在两种存储结构上实现的基本运算。循环队列重对边界条件的处理。