参考文章
实验7、矩阵的2种转置运算 (4学时)
5.3矩阵的压缩存储(稀疏矩阵转置和快速转置)
实验内容
用三元组表压缩存储矩阵,实现创建矩阵、显示以及教材中介绍的两种转置算法。
实验数据记录
创建, 输入:4(行数) 4(列数) 5(非零元个数)
(1,1,1) (2,3,2) (3,1,3) (3,4,5) (4,2,4)
检查是否能拦截元素重复输入
显示
屏幕上输出
1 0 0 0
0 0 2 0
3 0 0 5
0 4 0 0
转置
屏幕上输出
1 0 3 0
0 0 0 4
0 2 0 0
0 0 5 0
源码粘贴
//实验6矩阵的2种转置运算
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
#define MaxSize 10000
int book[10000][10000];
typedef struct//非零元素的行列坐标
{
int i, j, e; //i行j列元素e
} Tripe;
typedef struct
{
Tripe data[MaxSize+1];//非零元三元组表
int row, column, non_zero;//row行column列non_zero非零元素个数
} TSMatrix;
void xianshi()
{
cout << "*******************************************************" << endl;
cout << "********** 1.创建矩阵 **********" << endl;
cout << "********** 2.销毁矩阵 **********" << endl;
cout << "********** 3.输出矩阵M **********" << endl;
cout << "********** 4.转置矩阵 **********" << endl;
cout << "********** 5.快速转置矩阵 **********" << endl;
cout << "********** 6.转置矩阵对比 **********" << endl;
cout << "********** 7.退出 **********" << endl;
cout << "*******************************************************" << endl;
cout << "请输入选择:" << endl;
}
//1.创建矩阵
bool CreateMatrix( TSMatrix &T )
{
int i, j, k, e;
int x;//标记是否继续输入
cout << "请输入矩阵的行数,列数,非零元个数:" << endl;
cin >> (&T)->row >> (&T)->column >> (&T)->non_zero;
if( T.column*T.row < T.non_zero )//如果矩阵容量<非零元个数
{
cout << "输入非零元个数大于矩阵容量!矩阵创建失败!" << endl;
return false;
}
else if( T.non_zero <= 0 )
{
cout << "输入非零元个数无意义!矩阵创建失败!" << endl;
return false;
}
for( k=1; k<=T.non_zero; k++ )
{
do
{
printf("请输入第%d个非零元素的行(1~%d),列值(1~%d)和元素值:\n", k, T.row, T.column );
cin >> i >> j >> e;
x = 0;
if( book[i][j] )
{
cout << "该位置的元素已经被赋值!请重新输入!" << endl;
x = 1;
}
if( i<1 || i>T.row || j<1 || j>T.column )
{
cout << "输入的行列值不合法!" << endl;
cout << "请重新输入!" << endl;
x = 1;
}
if( i<T.data[k-1].i || i==T.data[k-1].i && j<T.data[k-1].j )
{
cout << "行列值输入错误!" << endl;
cout << "请重新输入!" << endl;
x = 1;
}
}
while(x);
T.data[k].i = i;
T.data[k].j = j;
T.data[k].e = e;
book[i][j] = 1;
}
cout << "矩阵创建成功!" << endl;
return true;
}
//2.销毁矩阵
bool DestroyMatrix( TSMatrix &T )
{
(&T)->row = 0;
(&T)->column = 0;
(&T)->non_zero = 0;
return true;
}
//3.输出矩阵M
bool PrintMatrix( TSMatrix T )
{
printf("该矩阵共有%d行%d列%d个非零元素。\n", T.row, T.column, T.non_zero);
int n=1;
for( int i=1; i<=T.row; i++ )
{
for( int j=1; j<=T.column; j++ )
{
if( n<=T.non_zero )
{
if( T.data[n].i == i && T.data[n].j == j )
{
cout << T.data[n].e <<' ';
n++;
}
else
cout << "0" << ' ';
}
else
cout << "0" << ' ';
}
cout << endl;
}
cout << endl;
cout << "矩阵输出完毕!" << endl;
return true;
}
//4.转置矩阵
bool TransposeMatrix( TSMatrix T, TSMatrix &t )//T为转置前的矩阵,t为转置后的矩阵
{
int r, c, n;
t.row = T.column;
t.column = T.row;
t.non_zero = T.non_zero;
if( t.non_zero )//矩阵中存在非零元时进行转置
{
r=1;
for( c=1; c<=T.row; c++ )
{
for( n=1; n<=T.non_zero; n++ )
{
if( T.data[n].j == c )//转置后的元素其列数等于转置前的行数
{
t.data[r].i = T.data[n].j;
t.data[r].j = T.data[n].i;
t.data[r].e = T.data[n].e;
++r;
}
}
}
}
cout << "转置后的矩阵为:"<< endl;
PrintMatrix( t );
return true;
}
//5.快速转置矩阵
bool QuickTransposeMatrix( TSMatrix M, TSMatrix &T )
{
int col;//用来遍历原矩阵M的列数
int t, p, q;
int num[20];//表示矩阵M中第col列中的非零元素个数。
int cpot[20];//表示矩阵M中第col列的第一个非零元在b.data的恰当位置
/*
有两个公式
cpot[1] = 1;//矩阵M中第1列的第一个非零元在b.data的位置为1
cpot[col] = cpot[col-1] + num[col-1];
//矩阵M中第col列的第一个非零元在b.data的位置为col-1列第一个非零元素的位置+col-1列的非零元素个数
*/
T.row = M.row;
T.column = M.column;
T.non_zero = M.non_zero;
if( T.non_zero )
{
for( col=1; col<=M.column; col++)
num[col] = 0;
for( t=1; t<=M.non_zero; t++ )//求矩阵M每一列的非零元素个数
++num[M.data[t].j];
cpot[1] = 1;
//求矩阵M中每一个非零元素在b.data中的序号
for( col=2; col<=M.column; col++)
cpot[col] = cpot[col-1] + num[col-1];
for( p=1; p<=M.non_zero; 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];
}//for
}//if
cout << "转置后的矩阵为:" << endl;
PrintMatrix(T);
return true;
}
//6.转置矩阵对比
bool CompareMatrix( TSMatrix T, TSMatrix &t )
{
cout << "转置前的矩阵为:"<< endl;
PrintMatrix(T);
cout << "转置后的矩阵为:" << endl;
PrintMatrix(t);
return true;
}
//7.退出
void exit()
{
cout << "操作结束,退出成功!" << endl;
exit(0);
}
void menu()
{
int operate_num;
bool continuedo=false;
TSMatrix T, t;
while( 1 )
{
cin >> operate_num;
switch( operate_num )
{
case 1: //1.创建矩阵
{
if( !continuedo )
{
CreateMatrix(T);
continuedo = true;
}
else
printf("矩阵已经初始化,不能重复初始化!\n\n\n" );
break;
}//case1
case 2 ://2.销毁矩阵
{
if( continuedo )
{
DestroyMatrix(T);
printf("矩阵销毁成功!\n\n\n");
continuedo = false;
}
else
printf("链队列没有初始化,无法销毁!\n\n\n");
break;
}//case2
case 3://3.输出矩阵
{
if( continuedo )
{
PrintMatrix(T);
}
else
printf("矩阵没有初始化,无法输出!\n\n\n");
break;
}//case3
case 4://转置矩阵
{
if( continuedo )
{
TransposeMatrix(T, t);
}
else
printf("矩阵没有初始化,无法转置!\n\n\n");
break;
}//case4
case 5://快速转置矩阵
{
if( continuedo )
{
QuickTransposeMatrix(T, t);
}
else
printf("矩阵没有初始化,无法快速转置!\n\n\n");
break;
}//case5
case 6://转置矩阵对比
{
if( continuedo )
{
CompareMatrix(T, t);
}
else
printf("矩阵没有初始化,无法进行转置矩阵对比!\n\n\n");
break;
}//case6
case 7:
{
exit();
break;
}
default:
{
cout << "输入操作数有误!" << endl << endl << endl;
break;
}//default
}//switch
}//while
}//menu()
int main()
{
xianshi();
menu();
return 0;
}