一、实验目的
1.熟悉稀疏矩阵的存储表示和实现技术。
2.熟练掌握稀疏矩阵的表示方法及其运算的C语言实现。
3.能够从空闲复杂度的角度分析稀疏矩阵压缩存储的优点及其适用场合。
4.培养学生利用稀疏矩阵的压缩存储解决实际问题的能力。
二、实验题目
1.稀疏矩阵A、B均采用三元组表表示,验证实现矩阵A快速转置算法,并设计、验证矩阵A、B相加得到矩阵C的算法。
(1)从键盘输入矩阵的行数和列数,随机生成稀疏矩阵。
(2)设计算法将随机生成的稀疏矩阵转换成三元组顺序表形式存储。
(3)设计算法将快速转置得到的与相加得到的三元组顺序表分别转换成矩阵形式。
(4)输出随机生成的稀疏矩阵A、B及其三元组顺序表、快速转置得到的与相加得到的三元组顺序表及其矩阵形式。
三、程序清单
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#define MAX 1000
typedef struct{
int i,j; //非零行存储稀疏矩阵非零元的行、列
int e; //非零元的具体值
}SP; //三元组定义
typedef struct{
SP data[MAX];
int mu,nu,tu; //稀疏矩阵行、列数
}SPMatrix;
int m,n,k;
void CreatMatrix(SPMatrix &t){ //创建三元组
int arr[100][100];
srand((unsigned)time(NULL));
printf("请输入矩阵的行数:");
scanf("%d",&m);
printf("请输入矩阵的列数:");
scanf("%d",&n);
for(int i=0;i<m*n/7;i++){
int a=rand()%n;
int b=rand()%m;
arr[a][b]=rand()%9+1;
}
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
printf("%d ",arr[i][j]);
}
printf("\n");
}
t.mu=m;
t.nu=n;
t.tu=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(arr[i][j]!=0){
t.data[t.tu].i=i;
t.data[t.tu].j=j;
t.data[t.tu].e=arr[i][j];
t.tu++;
}
}
}
}
void CreatMatrix1(SPMatrix &t){ //创建三元组
int arr[100][100];
srand((unsigned)time(NULL));
printf("请输入矩阵的行数:");
scanf("%d",&m);
printf("请输入矩阵的列数:");
scanf("%d",&n);
for(int i=0;i<m*n/6;i++){
int a=rand()%n;
int b=rand()%m;
arr[a][b]=rand()%9+1;
}
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
printf("%d ",arr[i][j]);
}
printf("\n");
}
t.mu=m;
t.nu=n;
t.tu=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(arr[i][j]!=0){
t.data[t.tu].i=i;
t.data[t.tu].j=j;
t.data[t.tu].e=arr[i][j];
t.tu++;
}
}
}
}
void TriplePrint(SPMatrix t){ //打印三元组
if(t.tu<=0)
return;
printf("i j e\n");
printf("%d %d %d\n",t.mu,t.nu,t.tu);
for(int i=0;i<t.tu;i++)
printf("%d %d %d\n",t.data[i].i,t.data[i].j,t.data[i].e);
}
void TransposeMatrix(SPMatrix M,SPMatrix &N){ //快速转置算法
N.mu=M.nu;
N.nu=M.mu;
N.tu=M.tu;
int num[100];
int cpot[100];
cpot[0]=0;
memset(num,0,100);
for(int i=0;i<M.tu;i++)
++num[M.data[i].j];
for(int col=1;col<M.nu;col++)
cpot[col]=cpot[col-1]+num[col-1];
for(int p=0;p<M.tu;p++){
int a=M.data[p].j;
int q=cpot[a];
N.data[q].e=M.data[q].e;
N.data[q].j=M.data[q].i;
N.data[q].i=M.data[q].j;
cpot[a]++;
}
}
void ShowMatrix(SPMatrix t){
int p,q;
int a=0;
for(p=0;p<t.mu;p++){
for(q=0;q<t.nu;q++){
if(t.data[a].i==p&&t.data[a].j==q){
printf("%d ",t.data[a].e);
a++;
}
else
printf("0 ");
}
printf("\n");
}
}
void FastAddSMatrix(SPMatrix A, SPMatrix B, SPMatrix &C) { //矩阵相加
C.mu=A.mu;
C.nu=A.nu;
C.tu=0;
int pa,pb,pc;
pa=pb=pc=0;
for(int row=0;row<A.mu;row++){
while(A.data[pa].i<row&&pa<=A.tu)
pa++;
while(B.data[pb].i<row&&pb<=B.tu)
pb++;
while(A.data[pa].i==row&&B.data[pb].i==row&&pa<=A.tu&&pb<=B.tu){
if(A.data[pa].j==B.data[pb].j){
int ce=A.data[pa].e+B.data[pb].e;
if(ce){
C.data[pc].i=row;
C.data[pc].j=A.data[pa].j;
C.data[pc].e=ce;
pa++;
pb++;
pc++;
}
}
else if(A.data[pa].j>B.data[pb].j){
C.data[pc].i=row;
C.data[pc].j=B.data[pb].j;
C.data[pc].e=B.data[pb].e;
pb++;
pc++;
}
else{
C.data[pc].i=row;
C.data[pc].j=A.data[pa].j;
C.data[pc].e=A.data[pa].e;
pa++;
pc++;
}
}
while(A.data[pa].i==row&&pa<=A.tu){
C.data[pc].i=row;
C.data[pc].j=A.data[pa].j;
C.data[pc].e=A.data[pa].e;
pa++;
pc++;
}
while(B.data[pb].i==row&&pb<=B.tu){
C.data[pc].i=row;
C.data[pc].j=B.data[pb].j;
C.data[pc].e=B.data[pb].e;
pb++;
pc++;
}
}
C.tu=pc;
}
int main(){
SPMatrix A,B,C,T,t;
printf("矩阵A\n");
CreatMatrix(A);
printf("矩阵B\n");
CreatMatrix1(B);
printf("A初始三元组为:\n");
TriplePrint(A);
printf("B的三元组为:\n");
TriplePrint(B);
TransposeMatrix(A,T);
printf("转置后A三元组为:\n") ;
TriplePrint(T);
FastAddSMatrix(A,B,C);
printf("转置后的A矩阵为:\n");
ShowMatrix(T);
printf("A、B矩阵相加得到的C矩阵为:\n");
ShowMatrix(C);
printf("C的三元组为:\n");
printf("%d %d %d\n",C.mu,C.nu,C.tu);
for(int i=0;i<C.tu;i++)
printf("%d %d %d\n",C.data[i].i,C.data[i].j,C.data[i].e);
}