稀疏矩阵
1、定义稀疏矩阵的数据结构,是个三元组
#include<stdio.h>
#define MAXSIZE 12500
typedef struct{
int i,j;
int e;
}Triple;
typedef struct{
Triple data[MAXSIZE+1];
int mu,nu,tu; //mu行数,nu列数,tu非零元个数
}TSMatrix;
2、基本操作:创建、销毁、打印稀疏矩阵
void CreateSMatrix_T(TSMatrix *M){
printf("输入行数:");
scanf("%d",&M->mu);
printf("输入列数:");
scanf("%d",&M->nu);
printf("输入非零元个数:");
scanf("%d",&M->tu);
for(int k=1;k<=M->tu;k++){
scanf("%d %d %d",&M->data[k].i,&M->data[k].j,&M->data[k].e);
}
}
void DestroySMatrix_T(TSMatrix *M){
M->nu=0;
M->nu=0;
M->tu=0;
}
void PrintSMatrix_T(TSMatrix M) {
if (M.tu) {
int r, c,dataflag=1;
for (r=1;r<= M.mu; r++) {
for (c = 1; c <= M.nu; c++) {
if (M.data[dataflag].j == c&&M.data[dataflag].i==r) {
printf("%3d", M.data[dataflag].e);
dataflag++;
}
else printf("%3d", 0);
}
printf("\n");
}
}
}
void CopySMatrix_T(TSMatrix M, TSMatrix *T){
(*T)=M;
}
3、加法器、减法器
```go
```c
//稀疏矩阵加法器
void AddSMatri_T(TSMatrix M, TSMatrix N, TSMatrix *Q){
if(M.mu==N.mu&&M.nu==N.nu){
Q->nu=M.nu;
Q->mu=M.mu;
Q->tu=0;
int r=1,c=1,m=1;
while(r<=M.tu&&c<=N.tu){
//先比较行数,行数优先
if(M.data[r].i<N.data[c].i){
Q->data[m++]=M.data[r++];
}
else if(M.data[r].i>N.data[c].i){
Q->data[m++]=N.data[c++];
}
//行数相等比较列数
else{
if(M.data[r].j<N.data[c].j){
Q->data[m++]=M.data[r++];
}
else if(M.data[r].j>N.data[c].j){
Q->data[m++]=N.data[c++];
}//如果行数和列数相等,则考虑数值相加是否为0
else{
if(M.data[r].e+N.data[c].e==0){
r++;c++;continue;
}else{
Q->data[m].i=M.data[r].i;
Q->data[m].j=M.data[r].j;
Q->data[m++].e=M.data[r++].e+N.data[c++].e;
}
}
}
Q->tu++;
}
while(r<=M.tu){
Q->data[m++]=M.data[r++];
}
while(c<=N.tu){
Q->data[m++]=N.data[c++];
}
}else{
printf("两矩阵不能相加");
}
}
//稀疏矩阵减法器
void SubSMatrix_T(TSMatrix M, TSMatrix N, TSMatrix *Q){ //M-N
if(M.mu==N.mu&&M.nu==N.nu){
Q->nu=M.nu;
Q->mu=M.mu;
int r=1,c=1,m=1;
while(r<=M.tu&&c<=N.tu){
//先比较行数,行数优先
if(M.data[r].i<N.data[c].i){
Q->data[m++]=M.data[r++];
}
else if(M.data[r].i>N.data[c].i){
Q->data[m].i=N.data[c].i;
Q->data[m].j=N.data[c].j;
Q->data[m++].e=-N.data[c++].e;
}
//行数相等比较列数
else{
if(M.data[r].j<N.data[c].j){
Q->data[m++]=M.data[r++];
}
else if(M.data[r].j>N.data[c].j){
Q->data[m].i=N.data[c].i;
Q->data[m].j=N.data[c].j;
Q->data[m++].e=-N.data[c++].e;
}//如果行数和列数相等,则考虑数值相加是否为0
else{
if(M.data[r].e-N.data[c].e==0){
r++;c++;continue;
}else{
Q->data[m].i=M.data[r].i;
Q->data[m].j=M.data[r].j;
Q->data[m++].e=M.data[r++].e-N.data[c++].e;
}
}
}
Q->tu++;
}
while(r<=M.tu){
Q->data[m++]=M.data[r++];
}
while(c<=N.tu){
Q->data[m].i=N.data[c].i;
Q->data[m].j=N.data[c].j;
Q->data[m++].e=-N.data[c++].e;
}
}else{
printf("两矩阵不能相减");
}
}
4、乘法器
//稀疏矩阵乘法器
int MultSMatrix_T(TSMatrix M, TSMatrix N, TSMatrix *Q){
int m,n,i,j,k;
int c,c1,c2; //c存放Q当前行列的值
if(M.nu!=N.mu) //M列数等于N行数
{
printf("两矩阵不能相乘!!\n");
return 0;
}
Q->mu = M.mu; //Q初始化
Q->nu = N.nu;
Q->tu = 0;
if(M.tu*N.tu) //Q是非零矩阵
{
for(i=1; i<=M.mu; i++) //传统矩阵乘法
{
for(j=1; j<=N.nu; j++)
{
c = 0;
for(k=1; k<=M.nu; k++) //k<= (M.nu==N.mu)
{
c1 = 0;
for(m=1; m<=M.tu; m++) //依次寻找位于指定位置的M三元组
{
if(M.data[m].i==i && M.data[m].j==k)
{
c1 = M.data[m].e;
break;
}
}
c2 = 0;
for(n=1; n<=N.tu; n++) //依次寻找位于指定位置的N三元组
{
if(N.data[n].i==k && N.data[n].j==j)
{
c2 = N.data[n].e;
break;
}
}
if(c1 && c2)
c += c1 * c2; //计算M(i,k)*N(k,j)的和
}
if(c)
{
Q->tu++;
Q->data[Q->tu].i = i;
Q->data[Q->tu].j = j;
Q->data[Q->tu].e = c;
}
}
}
}
return 1;
}
5、转置算法,包含一般转置和快速转置
//5.1矩阵转置
void TransposeSMatrix_T(TSMatrix M, TSMatrix *T){
T->mu=M.nu;T->nu=M.mu;T->tu=M.tu;
if(T->tu){
int q=1;
for(int col=1;col<=M.nu;col++) //先遍历列数,如果在M中存在,则放到T的行数中去
for(int 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++;
}
}
}
//5.2快速转置
void FastTransposeSMatrix_T(TSMatrix M, TSMatrix *T){
T->mu=M.nu;T->nu=M.mu;T->tu=M.tu;
int col,p,q;
int num[M.nu+1];
int cpot[M.nu+1];
if(T->tu){
for(col=1;col<=M.nu;col++) num[col]=0;
//求M中每一列含非零元的个数
for(int k=0;k<=M.tu;k++){
num[M.data[k].j]++;
}
cpot[1]=1;
//求第col列中第一个非零元在T.data中的序号
for(col=2;col<=M.nu;col++)
cpot[col]=cpot[col-1]+num[col-1]; //上一列的第一个元素的序号+上一列元素的个数
for(p=1;p<=M.tu;p++){
col=M.data[p].j; //存放当前列数
q=cpot[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;
cpot[col]++; //该个元素存完后,往后+1
}
}
}
6、测试函数
//测试函数
int main()
{
TSMatrix M, N;
int testsequence;
printf("请输入调试项目");
printf("1:函数CreateSMatrix_T测试\n");
printf("2:函数CopySMatrix_T测试\n");
printf("3:函数AddSMatri_T测试\n");
printf("4:函数SubSMatrix_T测试\n");
printf("5:函数MultSMatrix_T测试\n");
printf("6:函数TransposeSMatrix_T测试\n");
printf("7:函数FastTransposeSMatrix_T测试\n");
printf("0:退出调试\n");
scanf("%d",&testsequence);
while(testsequence) {
switch (testsequence) {
case 1: {
CreateSMatrix_T(&M);
PrintSMatrix_T(M);
printf("请输入调试项目");
scanf("%d", &testsequence);
break;
}
case 2: {
CreateSMatrix_T(&M);
PrintSMatrix_T(M);
CopySMatrix_T(M, &N);
printf("copy后的矩阵");
PrintSMatrix_T(N);
printf("请输入调试项目");
scanf("%d", &testsequence);
break;
}
case 3: {
TSMatrix Q;
CreateSMatrix_T(&M);
PrintSMatrix_T(M);
CreateSMatrix_T(&N);
PrintSMatrix_T(N);
AddSMatri_T(M, N, &Q);
printf("加法后的矩阵\n");
PrintSMatrix_T(Q);
printf("请输入调试项目");
scanf("%d", &testsequence);
break;
}
case 4: {
TSMatrix Q;
CreateSMatrix_T(&M);
PrintSMatrix_T(M);
CreateSMatrix_T(&N);
PrintSMatrix_T(N);
SubSMatrix_T(M, N, &Q);
printf("减法后的矩阵\n");
PrintSMatrix_T(Q);
printf("请输入调试项目");
scanf("%d", &testsequence);
break;
}
case 5: {
TSMatrix Q;
CreateSMatrix_T(&M);
PrintSMatrix_T(M);
CreateSMatrix_T(&N);
PrintSMatrix_T(N);
MultSMatrix_T(M, N, &Q);
printf("乘法后的矩阵:\n");
PrintSMatrix_T(Q);
printf("请输入调试项目");
scanf("%d", &testsequence);
break;
}
case 6: {
TSMatrix T;
CreateSMatrix_T(&M);
PrintSMatrix_T(M);
TransposeSMatrix_T(M, &T);
printf("转置后的矩阵:\n");
PrintSMatrix_T(T);
printf("请输入调试项目");
scanf("%d", &testsequence);
break;
}
case 7: {
TSMatrix T;
CreateSMatrix_T(&M);
PrintSMatrix_T(M);
FastTransposeSMatrix_T(M, &T);
printf("快速转置后的矩阵:\n");
PrintSMatrix_T(T);
printf("请输入调试项目");
scanf("%d", &testsequence);
break;
}
default: {
printf("请重新输入");
scanf("%d", &testsequence);
break;
}
}
}
return 0;
}