【数据结构】压缩特殊矩阵

矩阵是一种常用的数学对象,一般情况下,小的矩阵我们可以直接用二维数组直观方便地储存,但是在科学与工程计算问题中常会遇到较高阶数的矩阵,并且矩阵中会出现大量零元素,或者矩阵中的元素呈某种规律分布。如果在这种情况下仍然采用二维数组描述矩阵,看起来储存密度为1,实际上却占用了许多单元去储存零元素或重复的非零元素,从而会造成极大的浪费。为了节省储存空间,我们可以对这类矩阵进行储存压缩。

所谓的储存压缩是指:为矩阵中多个相同的元素只分配一个存储空间,对零元素不分配空间。特殊矩阵和稀疏矩阵是两类适合进行压缩存储的矩阵。本文先讲特殊矩阵,所谓的特殊矩阵是指非零元素分配有一定规律的矩阵,常见的特殊矩阵有对称矩阵、三角矩阵、三对角矩阵等。

对称矩阵:

在n阶方阵中,有a[i][j] == a[j][i]性质的,称为对称矩阵。
对称矩阵的元素关于主对角线对称,故只要存储矩阵中上三角部分或者下三角部分就可以。这相当于让每两个对称的元素共享存储空间,能节约近一半的空间。
这里存储下三角。
在对称矩阵的下三角部分中,第i行恰有i + 1个元素,总数为[n * (n + 1)] / 2.
因此,我们可以按照如下图所示的顺序将其存入到一个一维数组s中实现压缩存储。

对称矩阵下三角部分存储示意图

一维数组s的大小应该是[n * (n + 1)] / 2,其下标k的范围为0 ~ [n * (n + 1)] / 2 - 1;

这里写图片描述
图:对称矩阵压缩存储

为了访问对称矩阵A中的元素,我们必须在两者之间找到相应的对称关系:

若i >= j,则a[i][j]在下三角部分中,a[i][j]之前的i行一共有1+2+3+…+i = [i * (i + 1)] / 2个元素,在第i行上,a[i][j]之前恰有j个元素,因此有:k = [i * (i + 1)] / 2 + j (i >= j);

若i < j,在上三角部分中,因为a[i][j] == a[j][i],所以只要交换上式的i和j即可:k = [j * (j + 1)] / 2 + i (i < j);

三角矩阵:

三角矩阵是指主对角线以上或者以下均是常数c。

下三角矩阵:

下三角矩阵的存储方式和对称矩阵类似,不同之处在于除了存储下三角中的元素以外,还要存储对角线上方的常数。因为是同一个常数,所以只存一个即可。这样,一共存储了[n * (n + 1)] / 2 + 1个元素,将其存入数组s[n * (n + 1) / 2 + 1]中,任一元素下标的对应关系为:

k = [i * (i + 1)] / 2 + j  (i >= j);
k = [n * (n + 1)] / 2  (i < j);

上三角矩阵:

存储思想与下三角矩阵类似,只不过其第0行存储n个元素,第1行存储n - 1个元素…所以aij的前面有0~i-1共i行,存储着i * (2n - i + 1) / 2个元素,而aij是它所在行的第j-i+1个元素,所以,aij是一维数组中的第i * (2n - i + 1) / 2 + (j - i + 1)个元素,C++中的元素下标从0开始,因此元素aij在s中的下标为k = i * (2n - i + 1) / 2 + (j - i)

综上,上三角矩阵中任一元素aij下标的对应关系是:

k = i * (2n - i + 1) / 2 + (j - i)  (i <= j);
k = [n * (n + 1)] / 2  (i > j);

三对角矩阵:

三对角矩阵是指除了对角线以及离对角线最近的上下两边两斜行意外的其他元素均为0的矩阵。
同样,为了节省空间,我们只存储对角线及其上下两侧对角线上的元素,主次对角线以外的零元素均不存储。

矩阵第0行和第n-1行只有两个非零元素,其余各行有3个非零元素,总共有3n-2个非零元素.
所以,不在第0行的非零元素aij,他前面有3(i - 1) + 2个非零元素,而在本行中的j列前面有j-i+1个元素,所以元素aij在s中的位置k = 2i + j

这里写图片描述
图:三对角矩阵的压缩存储

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值