当前位置:
文档之家› 数据结构与STL_第4章_多维数组与广义表
数据结构与STL_第4章_多维数组与广义表
转置
data[0] data[1] data[2] data[3] data[4] data[5] … row col value 0 1 2 1 3 9 m=5 2 0 3 n=4 3 2 6 t=6 4 0 1 4 3 4 … … …
0 0 3 0 1
2 0 0 0 0
0 0 0 6 0
0 9 0 0 4
17
#define MAX_ELEMENT_NUMBER 1000 template <class T> struct MatrixNode //定义三元组结构 { int row; //非零元素的行号 int col; //非零元素的列号 T value; //非零元素的值 }; template <class T> struct SpareMatrix //定义三元组表结构 { int m; //稀疏矩阵的行数 int n; //稀疏矩阵的列数 int t; //稀疏矩阵非零元素的个数 MatrixNode <T> data[MAX_ELEMENT_NUMBER]; //存储非零元素对应的三元组 };
0 2 0 0 0 0 0 9 3 0 0 0 0 0 6 0 1 0 0 4 data[0] 0 2 3 data[1] 0 4 1 data[2] 1 0 2 data[3] 2 3 6 data[4] 3 1 9 data[5] 3 4 4 … … … … m=4 n=5 t=6
《数据结构与STL》
假设 m 行 n 列的矩阵含 t 个非零元素, 则称
t m n
为稀疏因子。
通常认为 0.05 的矩阵为稀疏矩阵。
《数据结构与STL》 16
4.2.2 稀疏矩阵压缩存储
存储稀疏矩阵时,只需要存储非零元素。常见的 稀疏矩阵压缩方法:三元组表和十字链表
稀疏矩阵中每个非零元素的行号、列号及值构成 row col value 一个三元组(3-tuples)
三对角矩阵
在存储对角矩阵时,可将对角线附近的带状区域元素 立起来,形成一个列数较少的新矩阵,然后可按行优 先方式存储这个新矩阵。
x 3 8 4 1 1 4 6 2 3 2 7 5 9 x x 1
第1行
2
3
4
第2 行
7
8
6
第3 行
5
4
2
第4 行
9
1
3
第5 行
14
《数据结构与STL》
n维m对角矩阵A(m为奇数),设其对角线附近的元素aij存储到 一维数组元素sa[k]中。由于aij在对角线附近,因此
对于n阶三角矩阵,需要存储n(n+1)/2+1个元素
《数据结构与STL》 11
上三角矩阵存储
按行优先存储n阶上三角矩阵,设aij存储到sa[k]中, 若aij位于矩阵上三角,有0≤i≤j<n,则在存储aij之前, sa数组中首先要存储前i行上三角的元素,然后再存储aij 所在行从aii到ai,j-1的元素
12
《数据结构与STL》
作业
按行优先存储n阶下三角矩阵时,首先存储下三 角的元素,最后存储上三角的常数项c。给出 aij与sa[k]的对应关系。
对于按列优先方式存储的n阶三角矩阵,请推导 元素存储位置k与下标i、j的对应关系
《数据结构与STL》
13
对角矩阵
所有非零元素都集中在对角线附近的方阵
1 3 0 0 0 2 4 8 0 0 0 7 6 4 0 0 0 5 2 1 0 0 0 9 3
《数据结构与STL》 3
行优先存储——基本思想是按行存储,即存完 第i行再接着存储第i+1行。按行优先顺序存储 二维数组Amn,线性序列为: a11,a12,…,a1n,a21,a22,…,a2n,…,am1,am2,…,amn
1 1 a11 j n
Loc(aij) =Loc(a11)+((i-1)×n+j-1)×c
max(i-(m-1)/2,0)≤j≤min(i+(m-1)/2,n-1)
aij之前共有i行,每行m个元素,首先要存储这mi个元素。 在aij所在行上,aij之前共有j-i+(m-1)/2个元素。 因此在存储aij之前,总共要存储mi+j-i+(m-1)/2个元素,即有: k=mi+j-i+(m-1)/2=(m-1)i+j+(m-1)/2
k ( (n l )) j i ni (i i ) / 2 j
2 l 0
i 1
若aij位于矩阵下三角,有0≤j<i<n,此时所有的aij具 有相同的值,只需保存1个值
k = n(n+1)/2 (0≤j<i<n)
a00 a01 a0n c a11 a 1n A c c ann
data[0] data[1] data[2] data[3] data[4] data[5] …
row col value 0 1 2 1 3 9 m=5 2 0 3 n=4 3 2 6 t=6 4 0 1 4 3 4 … … …
由于每趟遍历都需要比较所有的t个三元组的列号,因 此算法的时间复杂度为O(nt)。
x 3 8 4 1 1 4 6 2 3 2 7 5 9 x x 1
第1 行
1 3 0 0 0
2 4 8 0 0
0 7 6 4 0
0 0 5 2 1
0 0 0 9 3
2
3
4
第2 行
7
8
6
第3 行
5
4
2
第4 行
9
1
3
第5 行
15
《数据结构与STL》
4.2.2 稀疏矩阵压缩存储
矩阵Amn中的非零元素个数s远远小于矩阵元素 的总数m×n
《数据结构与STL》 18
稀疏矩阵的转置操作
0 2 0 0 0 0 0 9 3 0 0 0 0 0 6 0 1 0 0 4 data[0] data[1] data[2] data[3] data[4] data[5] … row col value 0 2 3 0 4 1 1 0 2 m=4 n=5 2 3 6 t=6 3 1 9 3 4 4 … … …
《数据结构与STL》
第四章 多维数组与广义表
北京邮电大学 信息与通信工程学院
第四章 多维数组和广义表
学习内容: 4.1 多维数组 4.2 矩阵的压缩存储 4.3 广义表 4.4 实例分析 4.5 使用STL操作多维数组 (计划学时2h)
《数据结构与STL》
2
4.1 多维数组
由类型相同的数据元素构成的有序集合。对于k 维数组,每个元素都要受k个线性关系的约束。
《数据结构与STL》 20
简单转置算法
//将稀疏矩阵OrigMat转置为TransMat template <class T> void TransMat(SpareMatrix <T> * OrigMat, SpareMatrix <T> * TransMat) { TransMat->m = OrigMat->n;//设置转置矩阵的行数 TransMat->n = OrigMat->m;//设置转置矩阵的列数 TransMat->t = 0;//初始时转置矩阵的非零元素个数为 for (int col=0;col<OrigMat->n;col++) for (int j=0;j<OrigMat->t;j++) if (OrigMat->data[j].col == col)//找出列号为col的三元组 { TransMat->data[TransMat->t].col = OrigMat->data[j].row ; TransMat->data[TransMat->t].row = OrigMat->data[j].col ; TransMat->data[TransMat->t].value = OrigMat->data[j].value ; TransMat->t++;//非零元素个数增 } }
特殊矩阵压缩存储 对称矩阵 三角矩阵 对角矩阵
稀疏矩阵压缩存储
《数据结构与STL》 8
对称矩阵
1 2 0 4 3
0 0 a00 a10 a11
共i行
2 0 7 8 1
0 7 6 5 4
j-1
4 8 5 2 9
j
3 1 4 9 3
n(n 1) 共需要存储的元素数目 k 2 k 1
n
设所有元素存储到一维数组sa中,aij 存储在sa[k]元素中,k与ij的关系?
共i-1行
a1 n
i
共j-1列
aij a11
aij之前共有(i-1)n+j-1个元素
… a1n a21 … a2n …
第1行 第2 行
ai1
… aij-1 aij
第i 行
…
ain
… amn
m
am 1
如果从a0开始: Loc( ) =Loc( a00)+(i×n+j)×c 在 C++a 、 等语言中,数组都是按行优先存储的 ijPASCAL
《数据结构与STL》
19
稀疏矩阵简单转置算法
遍历n趟三元组表:
•
• •
第一趟遍历找出列号为0的三元组,并将其行号和列号对调, 添加到转置矩阵对应的三元组表中。 第二趟遍历找出列号为1的三元组并进行相同的操作, 依次类推,最后一趟遍历找出列号为n-1的三元组。
data[0] data[1] data[2] data[3] data[4] data[5] … row col value 0 2 3 0 4 1 1 0 2 m=4 n=5 2 3 6 t=6 3 1 9 3 4 4 … … …