- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
5.3.2 稀疏矩阵
i(行) j(列) v(非0值) i(行) j(列) v(非0值)
0 1 2 3 4 5 6 7 8
6 1 1 3 3 4 5 6 6
7 2 3 1 6 3 2 1 4
8 12 9 -3 14 24 18 15 -7
0 1 2 3 4 5 6 7 8
7 1 1 2 2 3 3 4 6
5.3.2 稀疏矩阵
如何由M.data[ ]得到N.data[ ]呢?
可以将M.data [ ]中所有三元组的i和j的值互换, 则得到的N.data [ ]是一个按列优先顺序排列的 三元组表,然后再将它按行序排序,即得到转 置矩阵N的三元组顺序表。
但对数组的元素进行排序的时间复杂度将会达 到平方级。
5.2.1 特殊矩阵
在一个nn的三对角矩阵中,一共有n+n1+n-1=3n-2个非零元素,故只需3n-2个存储单元 即可,零元已不占用存储单元。即将其按行优 先的顺序压缩存储在数组sa[3n-2]中,其存储示意 图如下:
k=0 a11 1 a12 2 a21 3 a22 …… …… 3n-5 a n-1,n 3n-4 a n,n-1 3n-3
a a A= a10
00 10
a a
01
11
… … … a
a a
0,n-1
…
1,n-1
… a
… a
…
m-1,n-1
am-1,0 a01 a11
… …
m-1,0 m-1,1 …
am-1,1
5.2 数组的顺序表示和实现
由于二维数组的每个元素在内存中是顺序存储 的,因此,只要知道第一个元素的存储地址, 就可以求得其它元素的地址,如何求? 以行优先存储为例,假设设a00的内存地址为 LOC(a00),每个元素占用t个字节,则元素aij的 存储地址应为第一个元素的地址加上排在aij前 面的元素所占用的字节数,而aij的前面有i行 (0~i-1)共i×n个元素,而本行前面又有j个元素, 故aij的前面一共有i×n+j个元素。则aij的内存 地址按等差数列计算为:
typedef struct{ //定义稀疏矩阵 Triple data[maxsize]; //三元组表 int m, n, t; //稀疏矩阵行、列数、非零元个数 }TSMatrix; TSMatrix M,N;
5.3.2 稀疏矩阵
在结构体数组M.data[]中,表示非0元的三元组 是以行序为主序排列的。其中,M.data[0]未用, 可把行列值及非0元个数存入其中。
LOC(aij)=LOC(a00)+(i×n+j)×t
5.3 矩阵的压缩存储
矩阵是它是很多科学与工程计算问题中研究的 数学对象。高级语言中一般都用二维数组存储 矩阵,但有时候,对于一些阶数很高的矩阵, 如果在矩阵中有许多值相同的元素或者是零元 素,则会浪费存储空间。为了节省存储空间, 可以对这类矩阵进行压缩存储。 所谓压缩存储是指:为多个值相同的元素只分 配一个存储空间,值为零的元素不分配空间。 特殊矩阵:值相同的元素或者零元素在矩阵中 的分布有一定规律。 稀疏矩阵:元素分布无规律,零元素较多。
0 a11 1 2 3 ……
n( n+1) 2 -3 n( n+1) -2 2
n( n+1) -1 2
a21 a22 a31
……
a
n,n-2
a n,n-1
a n,n
则矩阵元aij 存储在sa[ ]数组中下标为多少(设 为k)的位置上呢?
5.3.1 特殊矩阵
有如下关系:
k=
{ j(j-1)/2+i-1 当 i<j
5.3.2稀疏矩阵
由此,一个稀疏矩阵可由表示非零元的三元组 序列和矩阵的行数、列数唯一确定。如下例:
A:稀疏矩阵M6×7
B:稀疏矩阵T7×6
5.3.2 稀疏矩阵
三元组线性表((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,8)(行数、列数、非零元个数)项,便 可作为矩阵M的存储描述了。同样,矩阵T也可 作类似表示。 三元组线性表可以采用顺序存储方式,也可以 采用链式存储结构,对应的也就是稀疏矩阵常 用两种压缩存储方式:三元组顺序表和十字链 表.重点介绍三元组顺序表。
5.2 数组的顺序表示和实现
例如二维数组A[m][n] 按行优先方式存储: a00,a01 ,…, a0,n-1,a10,a11,...,a 1,n-1 ,…, am-1,0 , am-1,1,…,am-1,n-1 a
a a A=
00 10
a
a
01
11
… … … a
a
a
a01
00
0,n-1
…
1,n-1
第五章 数组和广义表
5.1 5.2 5.3 5.4 5.5
数组的定义 数组的顺序表示和实现 矩阵的压缩存储 广义表的定义 广义表的存储结构
5.1 数组的定义
数组是大家都已经很熟悉的一种数据类型,几 乎所有高级语言程序设计中都设定了数组类型。 本章,我们仅简单地讨论数组的逻辑结构及在 计算机内的存储方式。 1 . 一维数组 一维数组可以看成是一个线性表,它在计算机 内是存放在一块连续的存储单元中,适合于随 机查找。
5.2.1 特殊矩阵
例如,下图为77的三对角矩阵(即有三条对角
线上元素非0)。
a 11 a 21 0 0 0 0 0 a 12 a 22 a 32 0 0 0 0 0 a 23 a 33 a 43 0 0 0 0 0 a 34 a 44 a 54 0 0 0 0 0 a 45 a 55 a 65 0 0 0 0 0 a 56 a 66 a 76 0 0 0 0 0 a 67 a 77
i(i-1)/2+j-1 当 i>=j ( 1≤ i,j≤n)
那么,aij和sa[k]之间的对应关系就可以由上 面的表达式确定。 由此,我们称sa[n(n+1)/2] 为n阶对称矩阵A 的压缩存储。
5.2.1 特殊矩角矩阵 即矩阵上三角部分元素是随机的,而下三角部 分元素全部相同(为某常数C)或全为0,具体 形式如下:
5.3.1 特殊矩阵
1.对称矩阵 若一个n阶方阵A中元素满足下列条件: aij=aji 其中1≤i,j≤n,则称A为对称矩阵。 如:
对称矩阵只需存储它的下三角元素或上三角元 素。一共只用存储n(n+1)/2 个元素即可。
5.3.1 特殊矩阵
假设以一维数组sa[0…n(n+1)/2](图示)作 为n阶对称矩阵A的存储结构,将矩阵的下 三角元素按行序存储到sa[]数组中.
5.3.2 稀疏矩阵
一、三元组顺序表 此时,数据类型可描述如下: #define maxsize 12500//定义非零元的最大数目 typedef struct //定义一个三元组 { int i, j; //非零元行号、列号 int v; //非零元的值 }Triple;
5.1 数组的定义
2.二维数组 如下图中,A是一个m行n列的二维数组. 二维数组也可以看成是一个定长的线性表.
a a A=
00 10
a
a
01
11
… … … a
a
a
0,n-1
1,n-1
… a
… a
…
m-1,n-1
m-1,0 m-1,1 …
5.1 数组的定义
则A可以表示为这样一个线性表: A=(a0,a1,…,an-1) 其中每个数据元素aj可以是一个列向量形式的 线性表: aj= ( a0j, a1j, …, am-1,j)
… a
… a
…
m-1,n-1
a0,n-1 a10 a11
… …
m-1,0 m-1,1 …
a1,n-1
5.2 数组的顺序表示和实现
二维数组A[m][n] 按列优先方式存储: a00,a10 ,…, am-1,0 , a01 , a11,..., am-1,1 ,…, a00 a0,n-1, a1,n-1 ,…, am-1,n-1
下面将介绍另外两种处理方法
5.3.2 稀疏矩阵
(1)按照M的列序进行转置 由于M的列即为N的行,因此,在M.data[]中, 按列值顺序进行扫描,则得到的N.data[]一定是按 行优先存放的。 方法:扫描M.data[]第1趟,找出M中所有第1列 的非0元素,交换行列值后,存入N.data[]。然后 再扫描M.data[]第2趟,找出M中第2列的所有非0元 素,交换行列值后,存入N.data[]。依次类推,M 共有多少列,则扫描多少趟。 为了能找出每一列中的所有非0元素,每趟扫 描都必须从M.data[]的第一行读到最后一行。
a11 a12 ... a1n c a 2n 22 ... a
压缩存储后其存储关系如下:
... ... ... ... k= c c c ann
{
(i-1)*(2n-i+2)/2+j-i 当 i≤j ( 1≤ i,j≤n) n(n+1)/2 当 i>j
5.2.1 特殊矩阵
(2) 下三角矩阵 即矩阵下三角部分元素是随机的,而上三 角部分元素全部相同(为某常数C)或全为0,具 体形式如下:
(0≤j≤n-1)
5.1 数组的定义
或者A可以表示为这样一个线性表: A=(a0, a1 , …, am-1) 其中,每个数据元素ai是一个行向量形式的线性表: ai=(ai0, ai1, ai2, …, ai,n-1) (0≤i≤m-1)