热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

矩阵压缩存储之三元组顺序表

形态:实现:*****************************************稀疏矩阵的三元组顺序表存储表示byRowandjj201453******************

形态:


实现:

/*****************************************
稀疏矩阵的三元组顺序表存储表示
by Rowandjj
2014/5/3
******************************************/
#include
using namespace std;

#define MAXSIZE 12500//非零元个数的最大值
typedef int ElemType;
typedef struct _DATA_
{
int i;//行下标
int j;//列下标
ElemType e;//元素值
}Data,*pData;
typedef struct _MATRIX_
{
Data data[MAXSIZE+1];//非零元三元组表,data[0]不用
int mu,nu,tu;//行数,列数,非零元个数
}Matrix,*pMatrix;


bool CreateMatrix(pMatrix pMatrixTemp);//创建稀疏矩阵M
bool ClearMatrix(pMatrix pMatrixTemp);//销毁稀疏矩阵
bool AddMatrix(pMatrix pMatrixTemp3,Matrix MatrixTemp1,Matrix MatrixTemp2);//矩阵求和
bool SubMatrix(pMatrix pMatrixTemp3,Matrix MatrixTemp1,Matrix MatrixTemp2);//矩阵减运算
bool MulMatrix(pMatrix pMatrixTemp3,Matrix MatrixTemp1,Matrix MatrixTemp2);//矩阵乘运算
void Convert(pMatrix pMatrixTemp3,Matrix MatrixTemp);//矩阵转置
void FastConvert(pMatrix pMatrixTemp3,Matrix MatrixTemp);//快速转置

void printMatrix(pMatrix pMatrixTemp);

int comp(int a,int b);
//-------------------------------------------
bool CreateMatrix(pMatrix pMatrixTemp)
{
printf("请输入矩阵行数,列数,非零元个数:\n");
scanf("%d",&pMatrixTemp->mu);
scanf("%d",&pMatrixTemp->nu);
scanf("%d",&pMatrixTemp->tu);

pMatrixTemp->data[0].i = 0;
int i;
int m,n;//行,列
ElemType e;//数据
bool bOk = false;
for(i = 1; i <= pMatrixTemp->tu;i++)
{
do
{
bOk = false;
printf("请按行序顺序输入第%d个非零元素所在的行(1~%d),列(1~%d),元素值:\n",i,pMatrixTemp->mu,pMatrixTemp->nu);
scanf("%d",&m);
scanf("%d",&n);
scanf("%d",&e);
if(m<1 || m>pMatrixTemp->mu || n<1 || n>pMatrixTemp->nu)//超出范围
{
bOk = true;
}
//行或列的顺序有错,要求后一个元素的行列值大于前一个元素
if(mdata[i-1].i || m==pMatrixTemp->data[i-1].i && n<=pMatrixTemp->data[i-1].j)
{
bOk = true;
}
} while (bOk);
//给三元组赋值
pMatrixTemp->data[i].e = e;
pMatrixTemp->data[i].i = m;
pMatrixTemp->data[i].j = n;
}
return true;
}
bool ClearMatrix(pMatrix pMatrixTemp)
{
pMatrixTemp->mu = 0;
pMatrixTemp->nu = 0;
pMatrixTemp->tu = 0;
return true;
}
bool AddMatrix(pMatrix pMatrixTemp3,Matrix MatrixTemp1,Matrix MatrixTemp2)
{
//1.只有两个矩阵的行和列相等时才能相加
if(MatrixTemp1.mu != MatrixTemp2.mu)
{
return false;
}
if(MatrixTemp1.nu != MatrixTemp2.nu)
{
return false;
}
//2.初始化和矩阵的行值和列值
pMatrixTemp3->mu = MatrixTemp1.mu;
pMatrixTemp3->nu = MatrixTemp1.nu;
//3.初始化指针,为每个矩阵添加头指针和尾指针
pData pStart1 = &MatrixTemp1.data[1];
pData pEnd1 = &MatrixTemp1.data[MatrixTemp1.tu];

pData pStart2 = &MatrixTemp2.data[1];
pData pEnd2 = &MatrixTemp2.data[MatrixTemp2.tu];
//和矩阵的头尾指针默认都指向非零元素首地址的前一位(0位未存储)
pData pStart3 = pMatrixTemp3->data;
pData pEnd3 = pMatrixTemp3->data;

//4.开始合并矩阵
while(pStart1<=pEnd1 && pStart2<=pEnd2)
{
pEnd3++;
switch(comp(pStart1->i,pStart2->i))
{
case 1:
*pEnd3 = *pStart1;
pStart1++;
break;
case 0:
switch(comp(pStart1->j,pStart2->j))
{
case 1:
*pEnd3 = *pStart1;
pStart1++;
break;
case 0:
*pEnd3 = *pStart1;
pEnd3->e += pStart2->e;
if(pEnd3->e==0)//结果为0的元素不需要存储到稀疏矩阵中
{
pEnd3--;
}
pStart1++;
pStart2++;
break;
case -1:
*pEnd3 = *pStart2;
pStart2++;
break;
}
break;
case -1:
*pEnd3 = *pStart2;
pStart2++;
break;
}
}
//剩余部分直接放到和矩阵
while (pStart1<=pEnd1)
{
pEnd3++;
*pEnd3 = *pStart1;
pStart1++;
}
while (pStart2<=pEnd2)
{
pEnd3++;
*pEnd3 = *pStart2;
pStart2++;
}
//非零元个数
pMatrixTemp3->tu = pEnd3-pStart3;
return true;
}
//a[n][m] * b[m][p] = a[n][p]
bool MulMatrix(pMatrix pMatrixTemp3,Matrix MatrixTemp1,Matrix MatrixTemp2)
{
//1.矩阵1的列必须和矩阵2的行相等
if(MatrixTemp1.nu != MatrixTemp2.mu)
{
return false;
}
//2.新矩阵的行为矩阵1的行,新矩阵的列为矩阵2的列
pMatrixTemp3->mu = MatrixTemp1.mu;
pMatrixTemp3->nu = MatrixTemp2.nu;
//3.动态申请临时数组存储新矩阵的元素值
ElemType *pBase = (ElemType*)malloc(sizeof(ElemType) * (pMatrixTemp3->mu*pMatrixTemp3->nu));
if(!pBase)
{
return false;
}

int i,j;
int l = MatrixTemp2.nu;//矩阵2的列值,也就是新矩阵的列值
//给数组赋初值 memset也行
for(i = 0 ; i mu*pMatrixTemp3->nu; i++)
{
*(pBase+i) = 0;
}

//4.将矩阵相乘后的值暂时存储到申请的一维数组中
for(i = 1; i <= MatrixTemp1.tu;i++)
{
for(j = 1; j <= MatrixTemp2.tu;j++)
{
/**
*矩阵相乘的规律,矩阵1的列值等于矩阵2的行值时才相乘
**/
if(MatrixTemp1.data[i].j == MatrixTemp2.data[j].i)
{
//存储到一维数组中
*(pBase + (MatrixTemp1.data[i].i-1)*l+MatrixTemp2.data[j].j-1) += MatrixTemp1.data[i].e*MatrixTemp2.data[j].e;
}
}
}
//5.将一维数组的元素放回新矩阵中
int t = 0;
for(i = 1; i <= MatrixTemp1.mu; i++)
{
for(j = 1; j <= MatrixTemp2.nu;j++)
{
t++;
pMatrixTemp3->data[t].e = *(pBase+(i-1)*l+j-1);
pMatrixTemp3->data[t].i = i;
pMatrixTemp3->data[t].j = j;
}
}
//6.释放一维数组
free(pBase);
pMatrixTemp3->tu = t;
return true;
}
bool SubMatrix(pMatrix pMatrixTemp3,Matrix MatrixTemp1,Matrix MatrixTemp2)
{
for(int i = 1; i <= MatrixTemp2.tu;i++)
{
MatrixTemp2.data[i].e *= -1;
}
AddMatrix(pMatrixTemp3,MatrixTemp1,MatrixTemp2);
return true;
}
void Convert(pMatrix pMatrixTemp3,Matrix MatrixTemp)
{
//适用条件 tu远小于mu*nu,否则时间复杂度将会很高
pMatrixTemp3->mu = MatrixTemp.nu;
pMatrixTemp3->nu = MatrixTemp.mu;
pMatrixTemp3->tu = MatrixTemp.tu;
int q = 1;
for(int i = 1; i <= MatrixTemp.nu; i++)
{
for(int j = 1; j<= MatrixTemp.tu; j++)
{
if(i == MatrixTemp.data[j].j)
{
pMatrixTemp3->data[q].i = MatrixTemp.data[j].j;
pMatrixTemp3->data[q].j = MatrixTemp.data[j].i;
pMatrixTemp3->data[q].e = MatrixTemp.data[j].e;
q++;
}
}
}
}
//快速转置
void FastConvert(pMatrix pMatrixTemp3,Matrix MatrixTemp)
{
int i,j,k,p;

pMatrixTemp3->mu = MatrixTemp.nu;
pMatrixTemp3->nu = MatrixTemp.mu;
pMatrixTemp3->tu = MatrixTemp.tu;

//1.计算原矩阵每一列的非零元个数,存储到数组中,num[0]不存储
int *num = (int*)malloc(sizeof(int)*(MatrixTemp.nu+1));
//2.计算原矩阵每一列第一个非零元在新矩阵pMatrixTemp3->data中的位置
int *cpot = (int*)malloc(sizeof(int)*(MatrixTemp.nu+1));
if(num == NULL || cpot==NULL)
{
return;
}
if(MatrixTemp.tu > 0)//原矩阵中存在非零元
{
for(i = 1; i <= MatrixTemp.nu;i++)
{
num[i] = 0;//每一列的非零元个数初始化为0
}
for(j = 1; j <= MatrixTemp.tu; j++)
{
++num[MatrixTemp.data[j].j];//求原矩阵每一列的非零元个数
}
cpot[1] = 1;
for(k = 2;k <= MatrixTemp.nu; k++)
{
//下一列第一个非零元位置为上一列第一个非零元位置加上上一列非零元的个数
cpot[k] = cpot[k-1]+num[k-1];
}
for(p = 1; p <= MatrixTemp.tu;p++)
{
j = MatrixTemp.data[p].j;
k = cpot[j];//在新矩阵中存储的位置

pMatrixTemp3->data[k].i = MatrixTemp.data[p].j;
pMatrixTemp3->data[k].j = MatrixTemp.data[p].i;
pMatrixTemp3->data[k].e = MatrixTemp.data[p].e;
++cpot[j];//更新存储位置
}
}
free(num);
free(cpot);
}
void printMatrix(pMatrix pMatrixTemp)
{
int i;
cout<<"行数,列数,元素值"< for(i = 1; i <= pMatrixTemp->tu; i++)
{
cout<data[i].i<<","<data[i].j<<","<data[i].e< }
}
int comp(int a,int b)
{
if(a > b)
{
return 1;
}else if(a == b)
{
return 0;
}else
{
return -1;
}
}

测试:

int main()
{
Matrix matrixTemp1 = {0};
CreateMatrix(&matrixTemp1);
//Matrix matrixTemp2 = {0};
//CreateMatrix(&matrixTemp2);

Matrix matrixTemp3 = {0};
// AddMatrix(&matrixTemp3,matrixTemp1,matrixTemp2);
// MulMatrix(&matrixTemp3,matrixTemp1,matrixTemp2);
Convert(&matrixTemp3,matrixTemp1);
printMatrix(&matrixTemp3);
cout<<"------------------"< FastConvert(&matrixTemp3,matrixTemp1);
printMatrix(&matrixTemp3);

return 0;
}



推荐阅读
author-avatar
苦蔷薇1988
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有