Download presentation
Presentation is loading. Please wait.
1
回顾 栈、队列、循环队列的定义、特征和描 述 栈、队列、循环队列的表示方法 栈、队列、循环队列的重要操作 递归的定义、分类及优缺点 递归与栈的关系 简单递归程序的编写
2
第四章 数组 数组的定义 数组的顺序表示和实现 矩阵的压缩存储
3
数组的 ADT 定义 数组的 ADT 定义 ADT Array{ 数据对象 : j i =0,…,b i -1, i=1,2,..,n, D={a j1j2…jn |n(>0) 为数组的维数, b i 为第 i 维长度,j i 是数组元素的第 i 维下标, a j1j2…jn ElemSet} 数据关系: R={R1,R2,…,Rn} Ri ={ | 0 j k b k -1,1 k n,k i, 0 j i b i -2, a j1…ji…jn, a j1…ji+1…jn D,i=2,…n}
4
基本操作: InitArray(&A,n,bound1,…,boundn) // 初始化 DestroyArray(&A) // 销毁 Value(A,&e,index1,…,indexn) // 读数组元素 Assign(&A,e,index1…,indexn) // 写数组元素 }ADT Array
5
数据元素个数为 每个元素都受着 n 个关系的约束 n=1 时, n 维数组退化为定长的线性表 n 维数组也可看为线性表的推广,如: 二维数组可看为一个定长线性表,其每个数据元素也是一个定长线性表 三维数组可看为一个定长线性表,其每个数据元素是一个二维数组 ………………………………. n 维数组可看为一个定长线性表,其每个数据元素也是一个 n-1 维数组
6
定义 相同类型的数据元素的集合。 一维数组的示例 35 27 49 18 60 54 77 83 41 02 0 1 2 3 4 5 6 7 8 9 一维数组
7
一维数组存储方式 35 27 49 18 60 54 77 83 41 02 0 1 2 3 4 5 6 7 8 9 l l l l l LOC(i) = LOC(i - 1)+l = a+i*l LOC(i) = LOC(i - 1)+l = a+i*l, i > 0 a, i = 0 a+i*l a
8
二维数组 行优先存放: 设数组开始存放位置 LOC( 0, 0 ) = a, 每个元 素占用 L 个存储单元 LOC ( i, j ) = a + ( n*i + j ) * L
9
三维数组 各维元素个数为 b 1, b 2, b 3 下标为 j 1, j 2, j 3 的数组元素的存储地址: (按页 / 行 / 列存放) LOC ( j 1, j 2, j 3 ) = a + (b 2 * b 3 * j 1 + b 3 * j 2 + j 3 ) * L 前 j 1 页总 元素个数 第 j 1 页的 前 j 2 行 总 元素个数
10
n 维数组的映象函数 各维长度为 b 1, b 2, b 3, …, b n 下标为 j 1, j 2, j 3, …, j n 的数组元素的存储地址 : LOC ( j 1, j 2, …, j n ) = a + (b 2 *b 3 *…*b n * j 1 + b 3 *b 4 *…*b n * j 2 + + ……+ b n * j n-1 + j n ) * L 其中 c n =L,c i-1 =b i *c i, 1<i n 即数组元素的存储位置是其下标的线性函数 随机存取结构
11
二维数组 三维数组 行向量 下标 i 页向量 下标 i 列向量 下标 j 行向量 下标 j 列向量 下标 k
12
数组的顺序存储表示 Typedef struct{ ElemType *base; // 数组元素基址 int dim; // 数组维数 int * bounds; // 数组维界基址 int * constants; // 数组映象函数常量基址 }Array
13
数组的初始化 Status InitArray(Array &A,int dim, … ){ A.dim=dim; A.bounds =(int *) malloc(dim* sizeof(int)); // 计算并分配数组元素空间 elemtotal=1; va_start(ap,dim); for (i=0;i<dim;++i){ A.bounds[i]=va_arg(ap,int); elemtotal *= A.bounds[i]; } va_end(ap); A.base = (ElemType *) malloc (elemtotal * sizeof(ElemType));
14
// 求映象函数的常数 ci, 并存入 A.constants[i-1] A.constants = (int *) malloc (dim * sizeof(int)); A.constants[dim-1]=1; // c n =L for (i =dim-2; i>=0;--i) // c i-1 =b i *c i, A.constants[i] = A.bounds[i+1]*A.constants[i+1]; return OK; }
15
数组元素的映象函数 Status Locate(Array A,va_list ap,int & off){ // 根据 ap 指示的各下标值,求出对应元素相对地址 off off=0; for ( i=0;i<A.dim;++i){ ind = va_arg(ap,int); off += A.constants[i]* ind; // 用映象函数求和值 } return OK; }
16
特殊矩阵的压缩存储 特殊矩阵:指非零元素或零元素的分布有 一定规律的矩阵。 特殊矩阵的压缩存储主要是针对阶数很高 的特殊矩阵。为节省存储空间,对可以不 存储的元素,如零元素或对称元素,不再 存储。 对称矩阵 三对角矩阵
17
对称矩阵的压缩存储 设有一个 n n 的对称矩阵 A 。 在矩阵中, a ij = a ji
18
为节约存储空间,只存对角线及对角线以上的元 素,或者只存对角线及对角线以下的元素。前者 称为上三角矩阵,后者称为下三角矩阵。 按行 把它们按行存放于一个一维数组 B 中,称之为对 称矩阵 A 的压缩存储方式。 数组 B 共有 n + ( n - 1 ) + + 1 = n*(n+1)/2 个元素。 对称矩阵的压缩存储
19
上三角矩阵上三角矩阵 下三角矩阵下三角矩阵
20
下三角矩阵下三角矩阵 sa a 11 a 21 a 22 a 31 a 32 a 33 …… a nn k= 0 1 2 3 4 5 6 7 8 n(n+1)/2-1 若 i j, 数组元素 A[i][j] 在数组 B 中的存放位置为 1 + 2 + + i-1 + j-1 = (i -1)* i / 2 + j-1 前 i-1 行元素总数 第 i 行第 j 个元素前元素个数
21
若 i < j ,数组元素 A[i][j] 在矩阵的上三角部分, 在数组 B 中没有存放,可以找它的对称元素 A[j][i]= j *(j -1) / 2 + i-1 综上,得到以下一一对应关系: i(i-1)/2+j-1 当 i j k = j(j-1)/2+i-1 当 i<j
22
三对角矩阵的压缩存储 sa a 11 a 12 a 21 a 22 a 23 a 32 a 33 a 34 … a nn-1 a nn 0 1 2 3 4 5 6 7 8 9 3n-3
23
稀疏矩阵 (Sparse Matrix) 非零元素个数远远少于矩阵元素个数 ( 稀疏因子 0.05)
24
ADT SparseMatrix{ 数据对象: D={a ij |i=1,2,…m;j=1,2,…,n; a ij Elemset,m 和 n 分别称为行数和列数 } 数据关系 :R={Row,Col} ………….. 基本操作: ………. MultSMatrix(M,N,&Q); // 矩阵乘积 TransposeSMatrix(M,&T); // 求转置矩阵 } ADT SparseMatrix 稀疏矩阵的 ADT 定义
25
稀疏矩阵的压缩存储-三元组表示
26
三元组顺序表 是三元组表的顺序存储结构表示 #define MAXSIZE 12500 Typedef struct{ int i,j; // 非零元的行下标和列下标 ElemType e; }Triple; Typedef struct{ Triple data[MAXSIZE +1]; // 非零元三元组表,以行序为主序 int mu,nu,tu; // 矩阵的行数、列数、非零元个数
27
作 业 6 作业: 5.2 5.6
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.