产出
CSDN 技术博客 1 篇
一、问题
实现稀疏矩阵(采用三元组表示)的基本运算
目的:领会稀疏矩阵三元组的存储结构及其基本算法设计。
内容:假设 nn 的稀疏矩阵 A 采用三元组表示,设计一个程序 exp6-1.cpp,实现如下功能:。
-
生成如下两个稀疏矩阵的三元组 a 和 b。
-
输出 a 转置矩阵的三元组。
-
输出 a+b 的三元组。
-
输出 ab 的三元组。
提示:本实验设计的功能算法如下
➢ CreatMat(TSMatrix &t,ElemType A[N][N]) //产生稀疏矩阵 A 的三元组表示 t
➢ DispMat(TSMatrix t) //输出三元组表示 t
➢ TranMat(TSMatrix t,TSMatrix &tb) //求三元组表示 t 的转置矩阵 tb
➢ MatAdd(TSMatrix a,TSMatrix b,TSMatrix &c) //求 c=a+b
➢ getvalue(TSMatrix t,int i,int j) //返回三元组 t 表示的 A[i][j]值
➢ MatMul(TSMatrix a,TSMatrix b,TSMatrix &c) //求 c=a×b
执行结果类似于下图:
二、思路分析
1、直接对三元组进行相关运算(该文代码思路)
2、先对稀疏矩阵进行运算,在生成三元组
三、代码实现
代码如下:
#include <stdio.h>
#define MaxSize 100//矩阵中非零元素最多个数
#define N 4 //稀疏矩阵行数
#define M 4 //稀疏矩阵列数
typedef int elem;
typedef struct
{
int r; //行数
int c; //列数
elem d; //数据元素
}TupNode; //三元组定义
typedef struct
{
int row; //行数值
int cols; //列数值
int nums; //非零元素个数
TupNode data[MaxSize]; //存放数组
}TSMatrix; //三元组顺序表定义
//生成稀疏矩阵A三元组
void CreatMat(TSMatrix &t, elem A[N][M])
{
int i, j;
t.row = N; //总行数
t.cols = M; //总列数
t.nums = 0; //总非零元素数,初始为零
for(i = 0; i < N; i++)//遍历数组A
{
for(j = 0; j < M; j++)
{
if(A[i][j] != 0) //判断是否为非零元素
{
t.data[t.nums].r = i; //记录非零元素所在的行数
t.data[t.nums].c = j; //记录非零元素所在的列数
t.data[t.nums].d = A[i][j]; //记录非零元素值
t.nums++; //非零元素个数加一
}
}
}
}
//输出三元组
void DipMat(TSMatrix t)
{
int i;
if(t.nums <= 0)//判断是否有非零元素
return;
printf("\t%d\t%d\t%d\n",t.row, t.cols, t.nums);
printf("-------------------------------------\n");
for(i = 0; i < t.nums; i++)
printf("\t%d\t%d\t%d\n",t.data[i].r, t.data[i].c, t.data[i].d);
}
//三元组转置
void TranTat(TSMatrix t, TSMatrix &tb)
{
int p, q = 0, v; //q为ta.data的下标,v进行计数,p为t.data的下标
tb.row = t.cols; //总行数和总列数互换
tb.cols = t.row;
tb.nums = t.nums; //非零元素个数
if(t.nums != 0) //当存在非零元素时进行转置
{
for(v = 0; v < t.cols; v++)//t列数为ta的行数
{
for(p = 0; p < t.nums; p++)
if(t.data[p].c == v)
{
tb.data[q].r = t.data[p].c;//行列互换
tb.data[q].c = t.data[p].r;
tb.data[q].d = t.data[p].d;//元素值传递
q++; //下一个data
}
}
}
}
//两个稀疏矩阵相加后对应的三元组
void MatAdd(TSMatrix a, TSMatrix b, TSMatrix &c)
{
if(a.row != b.row || a.cols != b.cols)//判断是否符合矩阵相加条件,即两矩阵行数和列数分别相等
{
printf("矩阵相加操作失败\n");
return;
}
c.row = a.row; //总行数赋值
c.cols = a.cols; //总列数赋值
int i = 0 , j = 0, k = 0;
while(i < a.nums || j < b.nums) //遍历两个三元组
{
if(a.data[i].r < b.data[j].r)//比较非零数值所在的行数大小,将较小的行数的非零数值放进c的三元组
{
c.data[k].r = a.data[i].r;
c.data[k].c = a.data[i].c;
c.data[k].d = a.data[i].d;
i++;
k++;
}
else if(a.data[i].r == b.data[j].r)//比较非零数值所在的行数大小,相等时
{
if(a.data[i].c < b.data[j].c)//比较非零数值所在的列数大小,将较小的列数非零数值放进c的三元组
{
c.data[k].r = a.data[i].r;
c.data[k].c = a.data[i].c;
c.data[k].d = a.data[i].d;
i++;
k++;
}
else if(a.data[i].c == b.data[j].c)//比较非零数值所在的列数大小,将两个非零元素相加的值放进c的三元组
{
c.data[k].r = b.data[j].r;
c.data[k].c = b.data[j].c;
c.data[k].d = a.data[i].d + b.data[j].d;
i++;
j++;
k++;
}
else //比较非零数值所在的列数大小,将较小的列数非零数值放进c的三元组
{
c.data[k].r = b.data[j].r;
c.data[k].c = b.data[j].c;
c.data[k].d = b.data[j].d;
j++;
k++;
}
}
else //比较非零数值所在的行数大小,将较小的行数数非零数值放进c的三元组
{
c.data[k].r = b.data[j].r;
c.data[k].c = b.data[j].c;
c.data[k].d = b.data[j].d;
j++;
k++;
}
}
c.nums = k;//非零元素个数
}
//返回三元组 t 表示的 A[i][j]值
int getvalue(TSMatrix t,int i,int j)
{
for(int k = 0; k < t.nums; k++)
{
if(t.data[k].r == i && t.data[k].c == j)
return t.data[k].d;
}
return 0;
}
//两个稀疏矩阵相乘后对应的三元组
void MatMul(TSMatrix a,TSMatrix b,TSMatrix &c)
{
if(a.cols != b.row) //判断是否满足两矩阵相乘的条件,即第一个矩阵的列数与第二矩阵的行数相等
{
printf("矩阵相乘操作失败\n");
return;
}
int i, j, k = 0, s;
c.row = a.row;
c.cols = b.cols;
for(i = 0; i < a.row; i++) //控制行数
{
for(j = 0; j < b.cols; j++) //控制列数
{
s = 0;
for(int m = 0; m < b.cols; m++)
{
s = s + getvalue(a, m, i)*getvalue(b, j, m);//第一个矩阵行的每个元素与第二个矩阵列的每个元素相乘,并将结果相加
}
if(s != 0) //如果数据元素不为0,则将其放进c三元组中
{
c.data[k].r = i;
c.data[k].c = j;
c.data[k].d = s;
k++;
}
}
}
c.nums = k; //总非零元素个数
}
int main()
{
TSMatrix t1, t2, c; //t1, t2为三元组
elem a[4][4] = {
{1,0,3,0},
{0,1,0,0},
{0,0,1,0},
{0,0,1,1}};
CreatMat(t1, a); //生成稀疏矩阵A三元组
printf("a的三元组:\n");
DipMat(t1); //输出三元组
elem b[4][4] = {
{3,0,0,0},
{0,4,0,0},
{0,0,1,0},
{0,0,0,2}};
CreatMat(t2, b); //生成稀疏矩阵B三元组
printf("b的三元组:\n");
DipMat(t2); //输出三元组
TranTat(t1, c); //三元组转置
printf("a转置后\n");
DipMat(c); //输出三元组
printf("c = a + b\nc的三元组:\n");
MatAdd(t1, t2, c); //计算两个稀疏矩阵相加后对应的三元组
DipMat(c); //输出三元组
printf("c = a * b\nc的三元组:\n");
MatMul(t1, t2, c); //矩阵相乘
DipMat(c); //输出三元组
return 0;
}