c语言稀疏矩阵转置矩阵
㈠ 求一个C++的稀疏矩阵类,要求能实现加法,减法和乘法,正常输出。还能转置。。。急!!!急!!!
#include <iostream.>
using namespace std;
const int MAXSIZE=100; // 定义非零元素的最多个数
const int MAXROW=10; // 定义数组的行数的最大值
typedef struct { // 定义三元组的元素
int i,j; //行数 列数
int e; //非零元的值
}Triple;
typedef struct { // 定义普通三元组对象
Triple data[MAXSIZE+1];
int a,b,c; //行数,列数,非零元个数
}TSMatrix;
typedef struct { // 定义带链接信息的三元组对象
Triple data[MAXSIZE+2];
int rpos[MAXROW+1];
int a,b,c;
}RLSMatrix;
template <class P>
int shuru(P & T,int y){ //输入矩阵,按三元组格式输入
cout<<"输入稀疏矩阵的行,列和非零元素个数:"<<endl;
cin>>T.a>>T.b>>T.c;
cout<<"请输出非零元素的位置和值:"<<endl;
int k=1;
for(;k<=T.c;k++)
cin>>T.data[k].i>>T.data[k].j>>T.data[k].e;
return 1;
}
template <class P>
void shuchu(P T){ // 输出矩阵,按标准格式输出
int m,n,k=1;
for(m=0;m<T.a;m++){
for(n=0;n<T.b;n++){
if((T.data[k].i-1)==m&&(T.data[k].j-1)==n){
cout.width(4);
cout<<T.data[k++].e;}
else{
cout.width(4); cout<<"0"; }
}
cout<<endl;
}
}
void zhuan( ) // 求矩阵的转置矩阵
{
TSMatrix M,T; //定义预转置的矩阵
shuru(M, 0); //输入矩阵
int num[MAXROW+1];
int cpot[MAXROW+1]; // 构建辅助数组
int q,p,t;
T.c=M.c; T.a=M.b; T.b=M.a;
if(T.c){
for(int col=1;col<=M.c;col++) num[col]=0;
for(t=1;t<=M.c;t++) ++num[M.data[t].j];
cpot[1]=1;
for(int i=2;i<=M.b;i++) cpot[i]=cpot[i-1]+num[i-1]; // 求出每一列中非零元素在三元组中出现的位置
for(p=1;p<=M.c;p++){
col=M.data[p].j; q=cpot[col];
T.data[q].i=col; T.data[q].j=M.data[p].i;
T.data[q].e=M.data[p].e; ++cpot[col];
}
}
cout<<"输入稀疏矩阵的转置矩阵为"<<endl;
shuchu(T);
}
void Count(RLSMatrix &T) // 求取每一行中非零元素在三元组中出现的位置
{
int num[MAXROW+1];
for(int col=1;col<=T.a;col++) num[col]=0;
for(col=1;col<=T.c;col++) ++num[T.data[col].i];
T.rpos[1]=1;
for(int i=2;i<=T.a;i++) T.rpos[i]=T.rpos[i-1]+num[i-1]; }
typedef struct OLNode // 定义十字链表元素
{
int i,j; //该非零元的行列下标
int e; //非零元值
struct OLNode *right,*down; // 该非零元所在行表和列表的后继元素
}OLNode,*OLink; typedef struct // 定义十字链表对象结构体
{
OLink *rhead,*chead; //
int a,b,c; // 系数矩阵的行数,列数,和非零元素个数
}CrossList; void CreateSMatrix_OL(CrossList & M) // 创建十字链表
{
int x,y,m;
cout<<"请输入稀疏矩阵的行,列,及非零元素个数"<<endl;
cin>>M.a>>M.b>>M.c;
if(!(M.rhead=(OLink*)malloc((M.a+1)*sizeof(OLink)))) exit(0);
if(!(M.chead=(OLink*)malloc((M.b+1)*sizeof(OLink)))) exit(0);
for(x=0;x<=M.a;x++)
M.rhead[x]=NULL; // 初始化各行,列头指针,分别为NULL
for(x=0;x<=M.b;x++)
M.chead[x]=NULL;
cout<<"请按三元组的格式输入数组:"<<endl;
for(int i=1;i<=M.c;i++){
cin>>x>>y>>m; // 按任意顺序输入非零元,(普通三元组形式输入)
OLink p,q;
if(!(p=(OLink)malloc(sizeof(OLNode)))) exit(0); // 开辟新节点,用来存储输入的新元素
p->i=x; p->j=y; p->e=m;
if(M.rhead[x]==NULL||M.rhead[x]->j>y){
p->right=M.rhead[x]; M.rhead[x]=p;
}
else{
for(q=M.rhead[x];(q->right)&&(q->right->j<y);q=q->right); // 查找节点在行表中的插入位置
p->right=q->right; q->right=p; // 完成行插入
}
if(M.chead[y]==NULL||M.chead[y]->i>x){
p->down=M.chead[y]; M.chead[y]=p;
}
else{
for(q=M.chead[y];(q->down)&&(q->down->i<x);q=q->down); // 查找节点在列表中的插入位置
p->down=q->down; q->down=p; // 完成列插入 }
}
} void shuchu(CrossList T){ // 输出十字链表,用普通数组形式输出
for(int i=1;i<=T.a;i++){
OLink p=T.rhead[i];
for(int j=1;j<=T.b;j++){
if((p)&&(j==p->j)){
cout<<p->e; p=p->right;
}
else
cout<<"0";
}
cout<<endl;
}
}
void chengfa() //矩阵的乘法
{
CrossList M,N; // 创建两个十字链表对象,并初始化
CreateSMatrix_OL(M);
CreateSMatrix_OL(N);
cout<<"输入的两稀疏矩阵的积为:"<<endl;
OLink pa,pb,pre ,hl[MAXROW+1]; //定义辅助指针,pa,pb分别为M,N当前比较的元素,pre为pa的前驱元素
for(int x=1;x<=M.b;x++) hl[x]=M.chead[x];
for(int k=1;k<=M.a;k++){ // 对M的每一行进行操作
pa=M.rhead[k]; pb=N.rhead[k]; pre=NULL;
while(pb){ // 把N中此行的每个元素取出,
OLink p;
if(!(p=(OLink)malloc(sizeof(OLNode)))) exit(0); // 开辟新节点,存储N中取出的元素
p->e=pb->e; p->i=pb->i; p->j=pb->j;
if(NULL==pa||pa->j>pb->j){ // 当M此行已经检查完或者pb因该放在pa前面
if(NULL==pre)
M.rhead[p->i]=p;
else
pre->right=p;
p->right=pa; pre=p;
if(NULL==M.chead[p->j]){ // 进行列插入
M.chead[p->j]=p; p->down=NULL;
}
else{
p->down=hl[p->j]->down; hl[p->j]->down=p;
}
hl[p->j]=p;
pb=pb->right;
}
else
if((NULL!=pa)&&pa->j<pb->j){ // 如果此时的pb元素因该放在pa后面,则取以后的pa再来比较
pre=pa; pa=pa->right;
}
else
if(pa->j==pb->j){ // 如果pa,pb位于同一个位置上,则将值相加
pa->e *= pb->e;
if(!pa->e){ // 如果相加后的和为0,则删除此节点,同时改变此元素坐在行,列的前驱元素的相应值
if(NULL==pre) // 修改行前驱元素值
M.rhead[pa->i]=pa->right;
else
pre->right=pa->right;
p=pa; pa=pa->right;
if(M.chead[p->j]==p) M.chead[p->j]=hl[p->j]=p->down; // 修改列前驱元素值
else
hl[p->j]->down=p->down;
free(p); pb=pb->right;
}
else{
pa=pa->right; pb=pb->right;
}
}
}
}
shuchu(M);
}
void jianfa() //矩阵的减法
{
CrossList M,N; // 创建两个十字链表对象,并初始化
CreateSMatrix_OL(M);
CreateSMatrix_OL(N);
cout<<"输入的两稀疏矩阵的差矩阵为:"<<endl;
OLink pa,pb,pre ,hl[MAXROW+1]; //定义辅助指针,pa,pb分别为M,N当前比较的元素,pre为pa的前驱元素
for(int x=1;x<=M.b;x++) hl[x]=M.chead[x];
for(int k=1;k<=M.a;k++){ // 对M的每一行进行操作
pa=M.rhead[k]; pb=N.rhead[k]; pre=NULL;
while(pb){ // 把N中此行的每个元素取出,
OLink p;
if(!(p=(OLink)malloc(sizeof(OLNode)))) exit(0); // 开辟新节点,存储N中取出的元素
p->e=pb->e; p->i=pb->i; p->j=pb->j;
if(NULL==pa||pa->j>pb->j){ // 当M此行已经检查完或者pb因该放在pa前面
if(NULL==pre)
M.rhead[p->i]=p;
else
pre->right=p;
p->right=pa; pre=p;
if(NULL==M.chead[p->j]){ // 进行列插入
M.chead[p->j]=p; p->down=NULL;
}
else{
p->down=hl[p->j]->down; hl[p->j]->down=p;
}
hl[p->j]=p;
pb=pb->right;
}
else
if((NULL!=pa)&&pa->j<pb->j){ // 如果此时的pb元素因该放在pa后面,则取以后的pa再来比较
pre=pa; pa=pa->right;
}
else
if(pa->j==pb->j){ // 如果pa,pb位于同一个位置上,则将值相加
pa->e -= pb->e;
if(!pa->e){ // 如果相加后的和为0,则删除此节点,同时改变此元素坐在行,列的前驱元素的相应值
if(NULL==pre) // 修改行前驱元素值
M.rhead[pa->i]=pa->right;
else
pre->right=pa->right;
p=pa; pa=pa->right;
if(M.chead[p->j]==p) M.chead[p->j]=hl[p->j]=p->down; // 修改列前驱元素值
else
hl[p->j]->down=p->down;
free(p); pb=pb->right;
}
else{
pa=pa->right; pb=pb->right;
}
}
}
}
shuchu(M);
} void add() //矩阵的加法
{
CrossList M,N; // 创建两个十字链表对象,并初始化
CreateSMatrix_OL(M);
CreateSMatrix_OL(N);
cout<<"输入的两稀疏矩阵的和矩阵为:"<<endl;
OLink pa,pb,pre ,hl[MAXROW+1]; //定义辅助指针,pa,pb分别为M,N当前比较的元素,pre为pa的前驱元素
for(int x=1;x<=M.b;x++) hl[x]=M.chead[x];
for(int k=1;k<=M.a;k++){ // 对M的每一行进行操作
pa=M.rhead[k]; pb=N.rhead[k]; pre=NULL;
while(pb){ // 把N中此行的每个元素取出,
OLink p;
if(!(p=(OLink)malloc(sizeof(OLNode)))) exit(0); // 开辟新节点,存储N中取出的元素
p->e=pb->e; p->i=pb->i; p->j=pb->j;
if(NULL==pa||pa->j>pb->j){ // 当M此行已经检查完或者pb因该放在pa前面
if(NULL==pre)
M.rhead[p->i]=p;
else
pre->right=p;
p->right=pa; pre=p;
if(NULL==M.chead[p->j]){ // 进行列插入
M.chead[p->j]=p; p->down=NULL;
}
else{
p->down=hl[p->j]->down; hl[p->j]->down=p;
}
hl[p->j]=p;
pb=pb->right;
}
else
if((NULL!=pa)&&pa->j<pb->j){ // 如果此时的pb元素因该放在pa后面,则取以后的pa再来比较
pre=pa; pa=pa->right;
}
else
if(pa->j==pb->j){ // 如果pa,pb位于同一个位置上,则将值相加
pa->e += pb->e;
if(!pa->e){ // 如果相加后的和为0,则删除此节点,同时改变此元素坐在行,列的前驱元素的相应值
if(NULL==pre) // 修改行前驱元素值
M.rhead[pa->i]=pa->right;
else
pre->right=pa->right;
p=pa; pa=pa->right;
if(M.chead[p->j]==p) M.chead[p->j]=hl[p->j]=p->down; // 修改列前驱元素值
else
hl[p->j]->down=p->down;
free(p); pb=pb->right;
}
else{
pa=pa->right; pb=pb->right;
}
}
}
}
shuchu(M);
} int main() //主函数
{
cout<<"1:稀疏矩阵的加法。"<<endl;
cout<<"2:稀疏矩阵的乘法。"<<endl;
cout<<"3:稀疏矩阵的减法。"<<endl;
cout<<"4:稀疏矩阵的转置."<<endl;
cout<<"0:退出程序。"<<endl;
char c=getchar();
if(c=='1')
add(); //调用矩阵相加函数
else
if(c=='2')
chengfa(); //调用矩阵相乘函数
else
if(c=='3')
jianfa(); //调用矩阵相减函数
else
if(c=='4')
zhuan( ); //调用矩阵转置函数
else
exit(0); //退出
return 0;
}
㈡ c语言矩阵转置问题
其实只是小问题,你自己都编的很好了。就是保存屏幕不在按入Q和Enter键屏幕不会马上消失上面有问题:
你可以用两个getchar()函数来读取键盘输入,前一个数缓冲enter键,后一个等待键盘输入,然后屏幕消失!
代码已修改,如下:
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 20 /*矩阵中最大非零元的个数*/
typedef struct triple
{
int i; /*行标,本程序中从1开始的*/
int j; /*列标,本程序中从1开始的*/
int e; /*非零元*/
}Triple; /*三元组定义*/
typedef struct tabletype
{
int mu; /*矩阵的行数*/
int nu; /*列数*/
int tu; /*非零元个数*/
Triple data[MAXSIZE+1]; /*非零元的三元组表,*/
}Tabletype; /*三元组线性表*/
void out_matrix(Tabletype *); /*输出 矩阵*/
/*以下为转置程序,将a所指矩阵转置,将结果存入b所指的矩阵中*/
int TransposeSMatrix(Tabletype *,Tabletype *);
int main( void )
{
char ch;
while(1)
{
printf(" @@@@@@@@@@本程序的功能是实现稀疏矩阵的普通转置@@@@@@@@@@@@@@@@@@@\n");
printf(" @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
/*源矩阵a*/
Tabletype a= {6,7,8,{ {1,2,12},{1,3,9},{3,1,-3},{3,6,14},{4,3,24},{5,2,18},{6,1,15},{6,4,-7} }};
Tabletype b; /*声明矩阵b*/
printf("The source Matrix:\n");
out_matrix(&a);
if(TransposeSMatrix(&a,&b)) /*若a不为零矩阵则转置a,存入b中*/
{ printf("After TransposeSMatrix: \n");
out_matrix(&b);
}
else
{
printf("The matrix is zeros:\n");
out_matrix(&a);
}
do{
printf("Input 'q' to quit and ENTER run again:");
if((ch = getchar()) == 'q' || ch == 'Q')
getchar(); //读取enter
getchar();//任意字符
exit(0);
}while(ch!='\n');
system("cls");
}
return 1;
}
void out_matrix(Tabletype *a) /* 打印矩阵*/
{
int i,j,k = 0;
for(i = 1 ;i <= a->mu; i++)
{
for(j = 1; j<= a->nu; j++)
{ /*判断是否为非零元*/
if((a->data[k].i == i)&&(a->data[k].j == j))
{
printf("%4d",a->data[k].e);
k++;
}
else
printf("%4d",0);
}
printf("\n");
}
}
int TransposeSMatrix(Tabletype *a,Tabletype *b)
{
int p,q,col;
b->mu = a->nu; /*原矩阵的行数为新矩阵的列数,愿列数为新行数,非零元个数不变*/
b->nu = a->mu;
b->tu = a->tu;
if(b->tu) /*若a不为零矩阵*/
{
q = 0; /*b->data下标*/
for(col = 1; col < a->nu; col++)
for(p = 0;p < a->tu;p++) /*p为a->data的下标*/
if(col == a->data[p].j) /*按b->data[q]中的列标对a->data[p]进行扫描*/
{
b->data[q].i = a->data[p].j;
b->data[q].j = a->data[p].i;
b->data[q].e = a->data[p].e;
q++;
}
return 1;
}
else /*a为零矩阵*/
return 0;
}
不知道是不是你的要求。希望能帮助你!
㈢ c++ 十字链表实现稀疏矩阵的转置
mplate <class Type>SparseMatrix<Type>
SparseMatrix<Type>::SparseMatrix::FastTranspose()
{
int *RowSize = new int[Cols]; // 统计各列非零元素个数
int *RowStart = new int[Cols]; // 预计转置后各行存放位置
SparseMatrix b; // 存放转置结果
b.Rows = cols; b.cols = Rows; b.Terms = Terms;
if (Terms>0) //nonzero matrix
{
for (int i=0;i<Cols;i++) RowSize[i] = 0; //initialize
for (i=0;i<terms;i++) RowSize[smArray[i].col]++;
//RowStart[i]=starting position of row i in b
RowStart[0]=0;
for (i=1;i<Cols;i++) RowStart[i] = RowStart[i-1]+
RowSize[i-1];
for (i=0;i<Terms;i++) //move from a to b
{
int j=Rowstart[smArray[i].col];
b.smArray[j].row=smArray[i].col;
b.smArray[j].col= smArray[i].row;
b.smArray[j].value= smArray[i].value;
RowStart[smArray[i].col]++;
} //end of for
}
delete [ ]Rowsize;
delete [ ]Rowstart;
return b;
}
另外,站长团上有产品团购,便宜有保证