(1)实验目的
通过该实验,让学生理解矩阵压缩存储的概念、方法等相关知识,掌握用三元组表方式如何进行矩阵的压缩存储,并在此基础上进行转置操作,理解转置和快速转置两种矩阵转置算法的思想。
(2)实验内容
用三元组表压缩存储矩阵,实现创建矩阵、显示以及教材中介绍的两种转置算法。
(3)参考界面(6.转置矩阵对比可以去掉)
(4)验收/测试用例
l 创建, 输入:4(行数) 4(列数) 5(非零元个数)
(1,1,1) (2,3,2) (3,1,3) (3,4,5) (4,2,4)
检查非零元素个数是否小于等于行数乘列数;检查是否能拦截元素重复输入;检查是否能控制输入的非零元素的下标是递增的(即按照行序输入,先输入小的下标,再输入较大的下标)。
l 显示
屏幕上输出
1 0 0 0
0 0 2 0
3 0 0 5
0 4 0 0
l 转置
屏幕上输出
1 0 3 0
0 0 0 4
0 2 0 0
0 0 5 0
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#define form 12500
int num1,num2,num3,num4;
typedef struct
{
int i,j;
int e;
}triple;
typedef struct
{
triple data[form+1];//三元组最大存储元素个数
int mu,nu,tu;//数组行数,列数,非零元素个数;
}TSMatrix;
void print(TSMatrix &M)
{
if(M.mu==0&&M.nu==0&&M.tu==0) printf("该矩阵已被销毁\n");
int p=1;
int d;
for(int a=0;a<M.mu;a++)
{
for(int b=0;b<M.nu;b++)
{
if((M.data[p].i-1)==a&&(M.data[p].j-1)==b)
{
d=M.data[p].e;
p++;
}
else d=0;
printf("%-4d",d);
}
printf("\n");
}
}
void TransposeSMatrix(TSMatrix M,TSMatrix &T) //求稀疏矩阵的一般算法
{
T.mu=M.mu; T.nu=M.nu; T.tu=M.tu;
int p,q,col;
if(T.tu)
{
q=1;
for(col=1;col<=M.nu;col++)
{
for(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++;
}
}
}
}
print(T);
}
void FastTransposeSMatrix(TSMatrix M,TSMatrix &Q) //快速转置算法
{
Q.mu=M.mu; Q.nu=M.nu; Q.tu=M.tu;
int p,q,t,col,*num,*cpot;
num=(int *)malloc((M.nu+1)*sizeof(int));
cpot=(int *)malloc((M.nu+1)*sizeof(int));
if(Q.tu)
{
for(col=1;col<=M.nu;col++) num[col]=0;
for(t=1;t<=M.tu;t++) num[M.data[t].j]++;
cpot[1]=1;
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];
Q.data[q].i=M.data[p].j;
Q.data[q].j=M.data[p].i;
Q.data[q].e=M.data[p].e;
cpot[col]++;
}
}
print(Q);
}
int main()
{
printf("*************************\n");
printf("****1.创建矩阵 *******\n");
printf("****2.销毁矩阵 *******\n");
printf("****3.输出矩阵M *******\n");
printf("****4.转置矩阵 *******\n");
printf("****5.快速转置矩阵*******\n");
printf("****6.转置矩阵对比*******\n");
printf("****7.退出 *******\n");
printf("*************************\n");
while(true)
{
TSMatrix M,T,Q;
printf("请输入选择:");
scanf("%d",&num1);
if(num1==7) break;
switch(num1)
{
case 1:
num2=0,num3=0,num4=0;
while(true)
{
printf("请输入行数,列数,非零元素个数:");
scanf("%d %d %d",&M.mu,&M.nu,&M.tu);
if(M.tu>(M.mu*M.nu))
{
printf("输入错误,非零元素个数大于总元素个数\n");
continue;
}
else
{
break;
}
}
for(int i=1;i<=M.tu;i++)
{
scanf("%d %d %d",&M.data[i].i,&M.data[i].j,&M.data[i].e);
if(M.data[i].i>M.mu)
{
printf("输入行数大于设定行数之内,输入无效\n");
i--;
}
if(M.data[i].j>M.nu||M.data[i].i<=0)
{
printf("输入列数不在设定列数之内,输入无效\n");
i--;
}
if(i>=2)
{
for(int j=1;j<i;j++)
{
if(M.data[i].i==M.data[j].i&&M.data[i].j<M.data[j].j)
{
num4=1;
break;
}
}
if(num4==1)
{
printf("在行数相同时,输入列数递减,请重新输入\n");
num4=0;
i--;
}
for(int j=1;j<i;j++)
{
if(M.data[i].i==M.data[j].i&&M.data[i].j==M.data[j].j)
{
num2=1;
break;
}
}
if(num2==1)
{
printf("输入重复,请重新输入\n");
num2=0;
i--;
}
for(int j=1;j<i;j++)
{
if(M.data[i].i<M.data[j].i)
{
num3=1;
break;
}
}
if(num3==1)
{
printf("输入行列小于上一个,请重新输入\n");
num3=0;
i--;
}
}
}
break;
case 2:
M.mu=0;
M.nu=0;
M.tu=0;
printf("矩阵已经被销毁\n");
break;
case 3:
print(M);
break;
case 4:
TransposeSMatrix(M,T);
break;
case 5:
FastTransposeSMatrix(M,Q);
break;
}
}
return 0;
}