数据结构--稀疏矩阵的快速转置及快速相乘操作
来源:互联网 发布:单片机按键输入 编辑:程序博客网 时间:2024/05/16 18:23
大家好!这一篇要写的是稀疏矩阵的快速转置和快速相乘的操作,我们都知道,在稀疏矩阵中对零元素进行存储和算术运算没什么必要,所以我们要减小这两个操作的复杂度,比如矩阵相乘的传统的经典算法中:
for(i=1;i<=M.行;++i)
for(j=1;j<=N.列;++j)
{
Q[i][j]=0;
for(k=1;k<=M.列;++k)
Q[i][j]+=M[i][k]*N[k][j];
}
光是Q[i][j]+=M[i][k]*N[k][j];这一句就要M的行数*N的列数再乘以M的列数这样一个复杂度,所以我们有了以下的算法,在快速相乘中我会写比较多的注释方便大家理解,具体详细的说明请各位参考严的数据结构,下面有三个文件,一个是Matrix.h,一个是Matrix.c,最后一个是main.c
//Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include <stdio.h>
#include <stdlib.h>
//#include <windows.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAXSIZE 7
#define MAXRC 7
#define ROW 4
#define COL 5
#define FORMAT "%3d"
#define TURNLINE printf("/n/n")
typedef int ElemType;
typedef int status;
typedef struct
{
int i,j;//行,列
ElemType e;//非零元素
}Triple;
typedef struct
{
Triple data[MAXSIZE+1];//非零元三元组表,data[0]不用
int mu,nu,tu;//矩阵的行数,列数及非零元个数
int rpos[MAXRC+1];//用于行逻辑链接的顺序表,即事先知道非零元在矩阵中每一行的位置,方便两个矩阵的快速相乘
}Matrix;
void test();
status createMatrix(Matrix *);//创建一个矩阵,这里留成空函数让大家自由发挥(因为这不是讨论的重点),下面自会有测试数据。
void printMatrix(Matrix M,int size);//打印矩阵
status findPostion(Matrix *);//查找矩阵中非零元的位置
status fastTransMatrix(Matrix ,Matrix *);//快速倒置矩阵
status multMatrix(Matrix ,Matrix ,Matrix *);//实现两个矩阵的快速相乘
void implement();//用于快速倒置矩阵的测试数据
void another_implement();//用于快速矩阵相乘的测试数据
#endif
//Matrix.c
#include "Matrix.h"
void test()
{
printf("step here...");
TURNLINE;
}
status createMatrix(Matrix *M)
{
return OK;
}
void printMatrix(Matrix M,int size)
{
int index;
printf("该矩阵的行数:%3d",M.mu);
printf("/t列数:%3d",M.nu);
printf("/t非零元的个数: %d",M.tu);
TURNLINE;
for(index=1;index<=size;++index)
{
printf(FORMAT,M.data[index].i);
printf(FORMAT,M.data[index].j);
printf(FORMAT,M.data[index].e);
TURNLINE;
}
}
status fastTransMatrix(Matrix M,Matrix *T)
{
int num[MAXSIZE+1];//每列非零元的个数
int cpot[MAXSIZE+1];//每列第一个非零元将在T中出现的位置
int col,t,p,q;
T->mu=M.nu;
T->nu=M.mu;
T->tu=M.tu;
if(T->tu)
{
for(col=1;col<=M.nu;++col)
{
num[col]=0;
}
for(t=1;t<=M.tu;++t)
{
++num[M.data[t].j]; //统计M中每列的非零元的个数
}
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];
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];
}
}
return OK;
}
status findPostion(Matrix *M)
{
int row,*num;
if(!M->tu) return ERROR;
num=(int *)malloc(sizeof(M->tu+1));
if(!num) return ERROR;
for(row=1;row<=M->mu;++row) num[row]=0;
for(row=1;row<=M->tu;++row) ++num[M->data[row].i];
M->rpos[1]=1;
for(row=2;row<=M->mu;++row) M->rpos[row]=M->rpos[row-1]+num[row-1];
free(*num);
return OK;
}
status multMatrix(Matrix M,Matrix N,Matrix *Q)
{
//传统的矩阵相乘算法
#if 0
for(i=1;i<=M.行;++i)
for(j=1;j<=N.列;++j)
{
Q[i][j]=0;
for(k=1;k<=M.列;++k)
Q[i][j]+=M[i][k]*N[k][j];
}
#endif
int Mrow,Nrow,pM,pN,*temp=NULL,t,tp,Qcol,i;
int row;
if(M.nu!=N.mu) return ERROR;
Q->mu=M.mu;
Q->nu=N.nu;
Q->tu=0;
if(M.tu*N.tu!=0)
{
temp=(int *)malloc(sizeof(N.nu+1));
if(!temp) return ERROR;
findPostion(&M);
findPostion(&N);
for(Mrow=1;Mrow<=M.mu;++Mrow)//通过处理M的每一行得到临时的Q的数据,因为相乘的结果不一定是非零元
{
for(i=1;i<=N.nu;++i) temp[i]=0;//用来临时存放Q的每一行里两列的累积和
Q->rpos[Mrow]=Q->tu+1;//是不是似曾似???没错,它就是用来统计Q中每一行第一个非零元的位置
if(Mrow<M.mu) t=M.rpos[Mrow+1];//提取M中每一行里的每一个非零元
else t=M.tu+1;
for(pM=M.rpos[Mrow];pM<t;++pM)
{
Nrow=M.data[pM].j;//找到N中对应位置的非零元以便进行相乘
if(Nrow<N.mu) tp=N.rpos[Nrow+1];//处理N中每一行中的每一个非零元
else tp=N.tu+1;
for(pN=N.rpos[Nrow];pN<tp;++pN)
{
Qcol=N.data[pN].j;
temp[Qcol]+=M.data[pM].e*N.data[pN].e ;
}
}
for(Qcol=1;Qcol<=N.nu;++Qcol)
{
if(temp[Qcol])
{
if(++Q->tu>MAXSIZE) return ERROR;
Q->data[Q->tu].i=Mrow;
Q->data[Q->tu].j=Qcol;
Q->data[Q->tu].e=temp[Qcol];
}
}
}
}
return OK;
}
void implement()//自己虚拟矩阵非零元素作测试
{
Matrix M,N,T;
M.mu=ROW;
M.nu=COL;
M.tu=7;
M.data[1].i=1;
M.data[1].j=2;
M.data[1].e=3;
M.data[2].i=1;
M.data[2].j=5;
M.data[2].e=-5;
M.data[3].i=2;
M.data[3].j=2;
M.data[3].e=-1;
M.data[4].i=3;
M.data[4].j=1;
M.data[4].e=6;
M.data[5].i=3;
M.data[5].j=4;
M.data[5].e=8;
M.data[6].i=4;
M.data[6].j=1;
M.data[6].e=-4;
M.data[7].i=4;
M.data[7].j=5;
M.data[7].e=7;
printMatrix(M,M.tu);
fastTransMatrix(M,&T);
printMatrix(T,T.tu);
}
void antother_implement()
{
Matrix M,N,Q;
M.mu=ROW;
M.nu=COL;
M.tu=7;
M.data[1].i=1;
M.data[1].j=2;
M.data[1].e=3;
M.data[2].i=1;
M.data[2].j=5;
M.data[2].e=-5;
M.data[3].i=2;
M.data[3].j=2;
M.data[3].e=-1;
M.data[4].i=3;
M.data[4].j=1;
M.data[4].e=6;
M.data[5].i=3;
M.data[5].j=4;
M.data[5].e=8;
M.data[6].i=4;
M.data[6].j=1;
M.data[6].e=-4;
M.data[7].i=4;
M.data[7].j=5;
M.data[7].e=7;
N.mu=5;
N.nu=2;
N.tu=5;
N.data[1].i=1;
N.data[1].j=2;
N.data[1].e=3;
N.data[2].i=2;
N.data[2].j=1;
N.data[2].e=2;
N.data[3].i=2;
N.data[3].j=2;
N.data[3].e=4;
N.data[4].i=3;
N.data[4].j=1;
N.data[4].e=1;
N.data[5].i=5;
N.data[5].j=2;
N.data[5].e=-2;
printMatrix(M,M.tu);
printMatrix(N,N.tu);
multMatrix(M,N,&Q);
printMatrix(Q,Q.tu);
}
//main.c
//#include "Matrix.h"
//#include "Matrix.c"
int main()
{
//implement();
antother_implement();
getchar();
return 0;
}
- 数据结构--稀疏矩阵的快速转置及快速相乘操作
- 数据结构----稀疏矩阵的快速转置
- 数据结构之稀疏矩阵的快速转置
- 稀疏矩阵的压缩存储及快速转置
- 【数据结构】稀疏结构及稀疏矩阵的压缩存储,矩阵的(快速)转置
- 稀疏矩阵的快速转置
- 稀疏矩阵的快速转置
- 稀疏矩阵的快速转置
- 稀疏矩阵的快速转置
- 稀疏矩阵的快速转置
- 稀疏矩阵的快速转置算法
- 稀疏矩阵的快速转置
- 稀疏矩阵的快速转置
- 数据结构 矩阵的快速转置 矩阵相乘(行逻辑连接顺序表)
- 稀疏矩阵快速转置
- 稀疏矩阵快速转置
- 稀疏矩阵快速转置
- C语言数据结构——稀疏矩阵的快速转置
- 求职遭遇的问题(C#和C++)。(2)
- 基带传输与频带传输
- 几种典型的局域网技术
- 使用EXT实现无刷新动态调用股票信息
- java类加载器学习笔记
- 数据结构--稀疏矩阵的快速转置及快速相乘操作
- Linux系统下tomcat服务器布署
- fallout3 辐射3 难句囧翻译1
- Head First C# 中文版 图文皆译 第十一章 事件和代理 page485
- 男人至少的道德底线(男女都该看)
- ubuntu server 网络设置和软件安装
- 尚学堂高清晰版本DRP---分享给大家哦!
- Exchange 2007 的存储理解
- 关于 flag