/**
* 实验题目:
* 实现稀疏矩阵(采用三元组表示)的基本运算
* 实验目的:
* 领会稀疏矩阵三元组的存储结构及其基本算法设计
* 实验内容:
* 假设n x n的稀疏矩阵A采用三元组表示,设计一个程序,实现如下功能:
* 1、生成如下两个稀疏矩阵的三元组a和b。
* 1 0 3 0 3 0 0 0
* 0 1 0 0 0 4 0 0
* 0 0 1 0 0 0 1 0
* 0 0 1 1 0 0 0 2
* 2、输出a转置矩阵的三元组
* 3、输出a+b的三元组
* 4、输出axb的三元组
*/
#include
#include
#define N 4
#define MAX_SIZE 100 // 矩阵中非零元素最多个数
typedef int ElemType;
typedef struct
{
int r; // 行号
int c; // 列号
ElemType d; // 元素值
}TupNode; // 三元组定义
typedef struct
{
int rows; // 行数值
int cols; // 列数值
int nums; // 非零元素个数
TupNode data[MAX_SIZE];
}TSMatrix; // 三元组顺序表定义
/*------------------------产生稀疏矩阵A的三元组表示t----------------------*/
static void create_matrix(TSMatrix &t, ElemType A[N][N])
{
int i, j;
t.rows = N; // 行数值
t.cols = N; // 列数值
t.nums = 0; // 非零元素个数
for(i = 0; i < N; i++)
{
for(j = 0; j < N; 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++; // 非零元素个数增1
}
}
}
}
/*------------------------输出三元组表示t----------------------*/
static void disp_matrix(TSMatrix t)
{
int i;
if(t.nums <= 0)
return;
printf("\t%d\t%d\t%d\n", t.rows, t.cols, t.nums);
printf("\t------------------\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);
}
/*------------------------求三元组表示t的转置矩阵tb----------------------*/
/**
* 转置矩阵:
* 把矩阵A的行换成相应的列,得到的新矩阵称为A的转置矩阵。
*/
static void tran_matrix(TSMatrix t, TSMatrix &tb)
{
int p, v;
int q = 0; // q为tb.data的下标
tb.rows = t.cols; // 转置矩阵行数值
tb.cols = t.rows; // 转置矩阵列数值
tb.nums = t.nums; // 转置矩阵非零元素个数
if(t.nums != 0)
{
for(v = 0; v < t.cols; v++) // tb.data[q]中的记录以c域的次序排列
{
for(p = 0; p < t.nums; p++) // p为t.data的下标
{
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++;
}
}
}
}
}
/*------------------------求c=a+b----------------------*/
static bool matrix_add(TSMatrix a, TSMatrix b, TSMatrix &c) // 引用类型形参c
{
int i = 0; // a中非零元素个数索引
int j = 0; // b中非零元素个数索引
int k = 0; // c中非零元素个数
ElemType v;
if(a.rows != b.rows || a.cols != b.cols) // 行数或列数不等时不能进行相加运算
return false;
// c的行列数与a的相同
c.rows = a.rows;
c.cols = a.cols;
while(i < a.nums && j < b.nums) // 处理a和b中的元素(假设 a.nums = 6, b.nums = 4)
{
if(a.data[i].r == b.data[j].r) // a元素的行号等于b元素的行号
{
if(a.data[i].c < b.data[j].c) // a元素的列号小于b元素的列号
{
// 将a元素添加到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;
k++;
i++;
}
else if(a.data[i].c > b.data[j].c) // a元素的列号大于b元素的列号
{
// 将b元素添加到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;
k++;
j++;
}
else // a元素的列号等于b元素的列号
{
v = a.data[i].d + b.data[j].d;
if(v != 0) // 只将不为0的结果添加到c中
{
c.data[k].r = a.data[i].r;
c.data[k].c = a.data[i].c;
c.data[k].d = v;
k++;
}
i++;
j++;
}
}
else if(a.data[i].r < b.data[j].r) // a元素的行号小于b元素的行号
{
// 将a元素添加到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;
k++;
i++;
}
else // a元素的行号大于b元素的行号
{
// 将b元素添加到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;
k++;
j++;
}
c.nums = k;
}
return true;
}
/*------------------------返回三元组t表示的A[i][j]值----------------------*/
static int get_value(TSMatrix t, int i, int j)
{
int k = 0;
while(k < t.nums && (t.data[k].r != i || t.data[k].c != j))
k++;
if(k < t.nums)
return t.data[k].d;
else
return 0;
}
/*------------------------求c=a*b----------------------*/
static bool matrix_mul(TSMatrix a, TSMatrix b, TSMatrix &c) // 引用类型形参c
{
int i;
int j;
int k;
int p = 0; // 矩阵c的非零元素个数
ElemType s;
if(a.cols != b.rows) // a的列数不等于b的行数时不能进行乘法运算
return false;
for(i = 0; i < a.rows; i++) // 矩阵c的行数
{
for(j = 0; j < b.cols; j++) // 矩阵c的列数
{
s = 0;
for(k = 0; k < a.cols; k++)
{
s = s + get_value(a, i, k) * get_value(b, k, j); // 求三元组元素
}
if(s != 0) // 产生一个三元组元素
{
c.data[p].r = i; // 三元组元素的行号
c.data[p].c = j; // 三元组元素的列号
c.data[p].d = s; // 三元组元素的元素值
p++;
}
}
}
c.rows = a.rows;
c.cols = b.cols;
c.nums = p; // 矩阵c的非零元素个数
return true;
}
int main(void)
{
ElemType a1[N][N] = {
{1, 0, 3, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 1, 1}
};
ElemType b1[N][N] = {
{3, 0, 0, 0},
{0, 4, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 2}
};
TSMatrix a, b, c;
create_matrix(a, a1);
create_matrix(b, b1);
printf("a的三元组:\n");
disp_matrix(a);
printf("b的三元组:\n");
disp_matrix(b);
printf("a转置为c\n");
tran_matrix(a, c);
printf("c的三元组:\n");
disp_matrix(c);
printf("c=a+b\n");
matrix_add(a, b, c);
printf("c的三元组:\n");
disp_matrix(c);
printf("c=a*b\n");
matrix_mul(a, b, c);
printf("c的三元组:\n");
disp_matrix(c);
return 0;
}
测试结果:
a的三元组:
4 4 6
------------------
0 0 1
0 2 3
1 1 1
2 2 1
3 2 1
3 3 1
b的三元组:
4 4 4
------------------
0 0 3
1 1 4
2 2 1
3 3 2
a转置为c
c的三元组:
4 4 6
------------------
0 0 1
1 1 1
2 0 3
2 2 1
2 3 1
3 3 1
c=a+b
c的三元组:
4 4 6
------------------
0 0 4
0 2 3
1 1 5
2 2 2
3 2 1
3 3 3
c=a*b
c的三元组:
4 4 6
------------------
0 0 3
0 2 3
1 1 4
2 2 1
3 2 1
3 3 2