一、矩阵的压缩存储
在数值分析中,经常出现一些阶数很高的矩阵,同时在矩阵中有许多值相同的元素或是零元素。有时为了节省存储空间,可以对这类矩阵进行压缩存储。所谓压缩存储是指:为多个值相同的元素只分配一个存储空间;对零元素不分配空间。
假若值相同的元素或者零元素在矩阵中的分布有一定规律,则我们称此类矩阵为特殊矩阵;反之称为稀疏矩阵。而三元组表则是用来存储稀疏矩阵的一种压缩方式。
什么是稀疏矩阵?
假设在m×n的矩阵中,有t个元素不为零。令δ = t / (m+n),称δ为矩阵的稀疏因子。通常认为
δ <= 0.05时,矩阵为稀疏矩阵。
以下是一些三元组表的操作,有判断矩阵是否对称,判断是否为稀疏矩阵,将矩阵进行转置。
#include <stdio.h>
#define Status int
#define OK 1
#define ERROR 0
#define MAXSIZE 12500
typedef struct Triple {
int i, j;//该非零元的行下标和列下标
int e;//非零元素值
}Triple;
typedef struct TSMatrix {
Triple data[MAXSIZE + 1];//非零三元组表,data[0]未用
int mu, nu, tu;//矩阵的行数、列数和非零元个数
}TSMatrix;
void PrintMatrix(TSMatrix M);
void InitMatrix(TSMatrix& M);
//判断是否为对称矩阵
Status JudgingSymmetry(TSMatrix M) {
int m, n;
for (m = 1; m <= M.tu; m++) {
for(n = 1;n <= M.tu;n++){
if (M.data[m].i == M.data[n].j && M.data[m].j == M.data[n].i) {//判断这个非零元的行(列)下标是否等于另一个非零元的列(行)下标,即两个元素是否对称
if (M.data[m].e != M.data[n].e)
return ERROR;
else
break;
}
}
}
return OK;
}
//判断矩阵是否为稀疏矩阵
bool JudgeSparse(TSMatrix M) {
int m, n, num = 0,p;
float temp;
m = M.mu;//矩阵的行数
n = M.nu;//矩阵的列数
for (p = 1; p <= M.tu; p++) {//记录矩阵中非零元的个数
num++;
}
temp = (float)(num) / (float)(m * n);
if (temp <= 0.05)
return true;
else
return false;
}
//将矩阵转置
Status TransposeSMatrix(TSMatrix M, TSMatrix& T) {
T.mu = M.mu;
T.nu = M.nu;
T.tu = M.tu;
int i, j, n = 1;
//printf("T.tu:%d,T.nu:%d,T.mu:%d\n", T.tu, T.nu, T.mu);
int q,col,p;
if (T.tu) {
q = 1;
for (col = 1; col <= M.nu; col++) {//按列转置
for (p = 1; p <= M.tu; p++) {
if (M.data[p].j == col) {
T.data[q].i = M.data[p].j;
T.data[q].j = M.data[p].i;
T.data[q].e = M.data[p].e;
q++;
}
}
}
}
for (i = 1; i <= T.tu; i++)
{
printf("i = %d ", T.data[n++].i);
}
printf("\n");
n = 1;
for (i = 1; i <= T.tu; i++)
{
printf("j = %d ", T.data[n++].j);
}
printf("\n");
n = 1;
for (i = 1; i <= T.tu; i++)
{
printf("e = %d ", T.data[n++].e);
}
printf("\n");
//PrintMatrix(M);
return OK;
}
//初始化一个矩阵
void InitMatrix(TSMatrix &M)
{
int i, j, p = 1;
for (i = 1; i <= M.mu; i++)
{
for (j = 1; j <= M.nu; j++)
{
M.data[p++].e = 0;
}
}
}
//打印矩阵
void PrintMatrix(TSMatrix M)
{
int i, j, p = 1;
for (i = 1; i <= M.mu; i++)
{
for (j = 1; j <= M.nu; j++)
{
if (i == M.data[p].i && j == M.data[p].j)
printf("%5d", M.data[p++].e);
else
printf("%5d", 0);
}
printf("\n");
}
printf("\n");
}
int main(void)
{
TSMatrix M,T;
M.mu = 4; M.nu = 4; M.tu = 6;
M.data[1].i = 1; M.data[1].j = 1; M.data[1].e = 3;
M.data[2].i = 1; M.data[2].j = 4; M.data[2].e = 5;
M.data[3].i = 2; M.data[3].j = 2; M.data[3].e = -1;
M.data[4].i = 3; M.data[4].j = 4; M.data[4].e = 9;
M.data[5].i = 4; M.data[5].j = 1; M.data[5].e = 5;
M.data[6].i = 4; M.data[6].j = 3; M.data[6].e = 8;
if (JudgingSymmetry(M))
printf("是对称矩阵!\n");
else
printf("不是对称矩阵!\n");
//PrintMatrix(M);
if (JudgeSparse(M))
printf("是稀疏矩阵!\n");
else
printf("不是稀疏矩阵!\n");
TransposeSMatrix(M, T);
PrintMatrix(T);
return 0;
}