设有采用三元组顺序表存储的两个稀疏矩阵M和N,试着编写一个算法,实现M和N相乘:
1.头文件:”TriSeqMatrix.h”
该文件夹中包含着三元稀疏矩阵的创建、初始化、转置、销毁等操作
#pragma once
#include
#include
#define MaxSize 200
typedef struct
/*三元组类型定义*/
{
int i;//非零元素的行
int j; //非零元素的列
DataType e;
}Triple;
typedef struct
/*矩阵类型定义*/
{
Triple data[MaxSize];
int m;//矩阵的行数
int n;
int len;//矩阵中非零元素的个数
} TriSeqMatrix;
int CreateMatrix(TriSeqMatrix *M)
//创建稀疏矩阵,按照行优先的顺序输入非零元素
{
int i, m, n;
int flag;
DataType e;
std::cout << "请输入稀疏矩阵的行数,列数,及非零元素额个数:\n";
scanf_s("%d,%d,%d", &M->m, &M->n, &M->len);
if (M->len > MaxSize)
return 0;
for (i = 0; i < M->len; i++)
{
do
{
printf("请按行序输入第%d个非零元素所在的行(0~%d),列(0~%d)元素值", i + 1, M->m - 1,M->n-1);
scanf_s("%d,%d,%d", &m, &n, &e);
flag = 0; //初始化标志位
if (m<0 || m>M->m || n<0 || n>M->m) //
flag = 1;
if (i > 0 && m < M->data[i - 1].i || m == M->data[i - 1].i&& n <= M->data[i - 1].j)
flag = 1;
} while (flag);
M->data[i].i = m;
M->data[i].j = n;
M->data[i].e = e;
}
return 1;
}
void CopyMatrix(TriSeqMatrix M, TriSeqMatrix *N)
/*将M的非零元素的行号,列号和值赋给N*/
{
N->len = M.len;
N->m = M.m;
int i;
for (i = 0; i < N->len; i++)
{
N->data[i].i = M.data[i].i;
N->data[i].j = M.data[i].j;
N->data[i].e = M.data[i].e;
}
}
void TransposeMatrix(TriSeqMatrix M, TriSeqMatrix *N)
/*稀疏矩阵的转置,按行搜索,找到后交换行列坐标,在按列排列即可*/
{
N->len = M.len;
N->m = M.n;
N->n = M.m;
int col, k, index;
index = 0;
for (col = 0; col < M.n; col++)//按列号扫描
{
for (k = 0; k < M.len; k++)
{
if (M.data[k].j == col)
{
N->data[index].i = M.data[k].j;
N->data[index].j = M.data[k].i;
N->data[index].e = M.data[k].e;
index++;
}
}
}
}
void FastTransposeMatrix(TriSeqMatrix M, TriSeqMatrix *N)
//快速转置
{
int *num,*position;
num = (int*)malloc((M.n+1) * sizeof(int));//num存储每一列非零元素的个数
memset(num, 0, sizeof(num));
position = (int *)malloc((M.n+1) * sizeof(int));//postion存储每一列第一个非零元素在行中的位置
int i,col,k;
for (i = 0; i < M.len; i++) //获取每一列非零元素的个数
{
col = M.data[i].j;
num[col]++;
}
position[0] = 0;
for (i = 1; i < M.n; i++) //获取每一列非零元素第一个元素在行中的位置
{
position[i] = position[i - 1] + num[i-1];
}
N->len = M.len;
N->m = M.n;
N->n = M.m;
for (i = 0; i < N->len; i++)//转置处理
{
col = M.data[i].j;
k = position[col]; // 找到了该列第一个非零元素应该存放的位置
N->data[k].i = M.data[i].j;
N->data[k].j = M.data[i].i;
N->data[k].e = M.data[i].e;
position[col]++;
}
free(num);
free(position);
}
void DestroyMatrix(TriSeqMatrix * M)
/*销毁稀疏矩阵*/
{
M->m = M->n = M->len = 0;
}
2.源文件
#include "pch.h"
#include
typedef int DataType;
#include"TriSeqMatrix.h"
int Compare(int a, int b)
{
if (a == b)
return 0;
else if (a < b)
return -1;
else
return 1;
}
int AddMatrix(TriSeqMatrix A, TriSeqMatrix B, TriSeqMatrix *C)
/*稀疏矩阵相加,比较每个非零元素的行号,列号,如果相同则进行加,如果不同将非零元素天入C,成功返回1,否则返回0*/
{
int a, b;
a = b = 0;
C->m = A.m;
C->n = A.n;
int k = 0;
C->len = 0;
if (A.m != B.m || A.n != B.n)
{
std::cout << "两个矩阵维数不同不可加";
return 0;
}
while(adata[k].e = A.data[a].e; //先赋值给C
C->len++;//长度加1;
C->data[k].i = A.data[a].i;
C->data[k].j = A.data[a].j;
a++;
k++;
}
break;
case 0: //A,B中行号相等,比较列号
{
switch (Compare(A.data[a].j,B.data[b].j))
{
case -1:
{
C->data[k].e = A.data[a].e; //先赋值给C
C->len++;//长度加1
C->data[k].i = A.data[a].i;
C->data[k].j = A.data[a].j;
a++;
k++;
}
break;
case 0:
{
if (A.data[a].e + B.data[b].e == 0)
{
a++;
b++;
}
else
{
C->data[k].e = A.data[a].e + B.data[b].e;
C->data[k].i = A.data[a].i;
C->data[k].j = A.data[a].j;
C->len++;
k++;
a++;
b++;
}
}
break;
case 1:
{
C->data[k].e = B.data[b].e; //先赋值给C
C->len++;//长度加1;
C->data[k].i = B.data[b].i;
C->data[k].j = B.data[b].j;
b++;
k++;
}
break;
default:
break;
}
}
break;
case 1://A中元素的行号比B小
{
C->data[k].e = B.data[b].e; //先赋值给C
C->len++;//长度加1;
C->data[k].i = B.data[b].i;
C->data[k].j = B.data[b].j;
b++;
k++;
}
break;
default:
break;
}
}
while (a < A.len)
{
C->data[k] = A.data[a];
k++;
a++;
C->len++;
}
while (b < B.len)
{
C->data[k] = B.data[b];
k++;
b++;
C->len++;
}
return 1;
}
int SubMatrix(TriSeqMatrix A, TriSeqMatrix B, TriSeqMatrix *C)
/*矩阵相减A-B*/
{
int i;
for (i = 0; i < B.len; i++)
{
B.data[i].e *= -1;
}
return AddMatrix(A, B, C);
}
void PrintMatrix(TriSeqMatrix M)
/*输出稀疏矩阵*/
{
int i;
printf("稀疏矩阵是%d行x%d列,共%d个非零元素。\n", M.m, M.n, M.len);
printf("行列元素值\n");
for (i = 0; i < M.len; i++)
{
printf("%2d%6d%8d\n", M.data[i].i, M.data[i].j, M.data[i].e);
}
}
int main()
{
TriSeqMatrix M, N, Q;
CreateMatrix(&M);
PrintMatrix(M);
CreateMatrix(&N);
PrintMatrix(N);
AddMatrix(M, N, &Q);
PrintMatrix(Q);
}