搜档网
当前位置:搜档网 › 稀疏矩阵的存储实现

稀疏矩阵的存储实现

稀疏矩阵的存储实现
稀疏矩阵的存储实现

课程设计任务书

学生姓名:宋吉松专业班级:软件1202班

指导教师:李晓红工作单位:计算机科学与技术学院题目: 稀疏矩阵的存储实现

初始条件:

理论:学习了《数据结构》课程,掌握了一种计算机高级语言。

实践:计算机技术系实验中心提供计算机及软件开发环境。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写

等具体要求)

1、系统应具备的功能:

(1)实现稀疏矩阵的三元组和十字链表两种存储结构

(2)实现稀疏矩阵的基本运算

(3)输出结果

2、数据结构设计;

3、主要算法设计;

4、编程及上机实现;

5、撰写课程设计报告,包括:

(1)设计题目;

(2)摘要和关键字(中文和英文);

(3)正文,包括引言、需求分析、数据结构设计、算法设计、有关技术的讨论、设计体会等;

(4)结束语;

(5)参考文献。

时间安排:2013年12月16日--25日

指导教师签名:李晓红 2013年12月14日系主任(或责任教师)签名:年月

摘要本课程设计在学习数据结构的前提下,运用c语言,对稀疏矩阵进行三元组存储和十字链表存储,并完成稀疏矩阵的转置,相加,相乘等基本运算。关键词稀疏矩阵三元组十字链表基本运算

Abstract This course is designed on the premise of learning data

structures using c language, for sparse matrix triple store to store and cross-linked, and were achieved under the two storage sparse matrix transpose, add, multiply, and other basic operations.

Keywords sparse matrix triples Crusaders basic operations

目录

引言 (1)

1 需求分析

1.1稀疏矩阵三元组表和十字链表两种存储的实现 (2)

1.2稀疏矩阵转置 (2)

1.3稀疏矩阵的相加相乘 (2)

1.4输出结果 (2)

2 数据结构设计

2.1 三元组的结构体 (2)

2.2 十字链表的结构体 (3)

3算法设计

3.1三元组

3.1.1三元组的创建 (3)

3.1.2三元组的转置 (5)

3.1.3三元组的相加 (5)

3.1.4三元组的相乘 (8)

3.1.5三元组的显示 (10)

3.2十字链表

3.2.1十字链表的创建 (11)

3.2.2十字链表的显示 (12)

3.3 主函数 (13)

4 设计体会 (16)

5 结束语 (16)

附1 参考文献 (16)

附2 源代码 (17)

附3 运行结果 (38)

引言

什么是稀疏矩阵?人们无法给出确切的定义,它只是一个凭人们的直觉来了解的概念。假设在m×n的矩阵中,有t个元素不为零。令q=t/(m×n),称q为矩阵的稀疏因子。通常认为q<=0.05时称为稀疏矩阵。

按照压缩存储的概念,值存稀疏矩阵的非零元。因此,除了寻出非零元的值外,还必须同时记下它所在的行和列的位置。反之,一个三元组唯一确定了矩阵A 的一个非零元。由此,稀疏矩阵可由表示非零元的三元组及其行列数唯一确定。其存储方法有三种,分别是三元组顺序表,行逻辑链接的顺序表,十字链表。分别是以顺序存储结构,带行连接信息的三元组表,及链式存储结构进行存储表示。

1需求分析

1.1稀疏矩阵三元组表和十字链表两种存储的实现

三元组表的实现通过建立两个结构体,分别用来表示三元组的行数、列数、非零元数和元素的行、列坐标、值。然后通过for循环进行赋值。并求出每行含有的非零元个数。十字链表与三元组的不同在于用链表来存储每一行,每一列的元素信息。

1.2稀疏矩阵的转置

稀疏矩阵的转置即将行列值进行调换,将元素的行列值进行调换,重排每个元素的次序。如何重排?三元组按照原矩阵M的列序进行转置。为了找到M的每个元素,要对三元组表从第一行开始进行扫描,便可得到转置后矩阵的顺序。十字链表需要将元素的行指针和列指针调换。

1.3稀疏矩阵的相加相乘

两个矩阵相加及每个元素分别对应相加。

两个矩阵的相乘M×N=S,即M的行元素与N的列元素分别对应乘积的累加,得到的即为S以M的行,N的列为坐标的元素的值。

1.4输出结果

可以用for或while循环,输出两种表示下的稀疏矩阵。

2 数据结构设计

2.1 三元组的结构体

typedef struct{

int i,j; //三元组每个元素的行坐标,列坐标,值int e;

}Triple;

typedef struct{

Triple data[MAXSIZE+1];

int rpos[MAXSIZE + 1]; //三元组各行第一个元素的位置

int mu,nu,tu; //三元组矩阵的行数,列数,非零元个数}TSMatrix; //三元组结构体定义;

2.2 十字链表的结构体

typedef struct OLNode{

int i,j;

int e; //十字链表每个元素的行坐标,列坐标,值struct OLNode *right,*down;

}OLNode,*OLink;

typedef struct {

int mu,nu,tu; //矩阵的行数,列数,非零元个数OLink *rhead,*chead; //行和列头指针

}CrossList; //十字链表结构体定义

3算法设计

3.1.1三元组的创建

void CreateSMatrix(TSMatrix &M){

//采用三元组顺序表存储表示,创建稀疏矩阵M

printf("请输入稀疏矩阵的行数列数非零元个数:\n");

scanf("%d%d%d",&M.mu,&M.nu,&M.tu);

if((M.mu<=0)||(M.nu<=0)||(M.tu<=0)||(M.tu>M.mu*M.nu))

//判断行值、列值、元素个数是否合法

printf("输入有误!");

for(int i=1;i<=M.tu;i++){ //输入稀疏矩阵元素

printf("请输入请输入非零元的行坐标列坐标值:");

scanf("%d%d%d",&M.data[i].i,&M.data[i].j,&M.data[i].e);

if((M.data[i].i<=0)||(M.data[i].j<=0)){

printf("输入错误,请重新输入!");

scanf("%d%d%d",&M.data[i].i,&M.data[i].j,&M.data[i].e);

}//if

}//for

int num[100];

if(M.tu)

{int i;

for(i = 1; i <= M.mu; i++) num[i] = 0; //初始化

for(int t = 1; t <= M.tu; t++) ++num[M.data[t].i]; //求M中每一行含非零元素个数

//求rpos

M.rpos[1] = 1;

for(i = 2; i <= M.mu; i++) M.rpos[i] = M.rpos[i-1] + num[i-1];

}

}//创建三元组

3.1.2三元组的转置

void TransposeSMatrix(TSMatrix M,TSMatrix &T){

T.nu=M.mu; //通过三元组表示,将M转置为T

T.mu=M.nu;

T.tu=M.tu;

int q=1;

for(int col=1;col<=M.nu;col++)

for(int 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++;

} //三元组转置

3.1.3三元组的相加

int Compare(int a1,int b1,int a2,int b2){ //先建立Compare函数

if(a1>a2)return 1;

else if(a1

else if(b1>b2)return 1;

if(b1

else return 0;

}

void AddTMatix(TSMatrix M,TSMatrix T,TSMatrix &S){ //矩阵S存放相加后的矩阵

S.mu=M.mu>T.mu?M.mu:T.mu; //对S矩阵的行数赋值

S.nu=M.nu>T.nu?M.nu:T.nu; //对S矩阵的列数赋值

S.tu=0;

int ce;

int q=1;int mcount=1,tcount=1;

while(mcount<=M.tu&&tcount<=T.tu){

switch(Compare(M.data[mcount].i,M.data[mcount].j,T.data[tcount].i,T.data[tcount].j) )

//用switch分支语句,用compare函数对需要相加的两个矩阵的某元素行数列数进行比较

{case -1: S.data[q].e=M.data[mcount].e; S.data[q].i=M.data[mcount].i;

S.data[q].j=M.data[mcount].j; q++;

mcount++;

break;

case 1: S.data[q].e=T.data[tcount].e; S.data[q].i=T.data[tcount].i;

S.data[q].j=T.data[tcount].j; q++;

tcount++;

break;

case 0: ce=M.data[mcount].e+T.data[tcount].e;//其他情况下把两个矩阵的值相加if(ce){ S.data[q].e=ce;

S.data[q].i=M.data[mcount].i;

S.data[q].j=M.data[mcount].j;

q++;

mcount++;

tcount++;}

else {mcount++;

tcount++;}

break;

while(mcount<=M.tu){

S.data[q].e=M.data[mcount].e;

S.data[q].i=M.data[mcount].i;

S.data[q].j=M.data[mcount].j;

q++;

mcount++; }//在case=-1的情况下对S矩阵的非零值,行数,列数进行赋值while(tcount<=M.tu){

S.data[q].e=T.data[tcount].e;

S.data[q].i=T.data[tcount].i;

S.data[q].j=T.data[tcount].j;

q++;

tcount++;

}//在case=1的情况下对S矩阵的非零值,行数,列数进行赋值

S.tu=q-1;

}//三元组相加

3.1.4三元组的相乘

int MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)

{

int arow, brow, ccol, i, t, ctemp[100], p, q, tp;//定义相乘函数中所需要用到的变量

if(M.nu != N.mu) return 0;//如果第一个矩阵的行数不等于第二个矩阵的列数,则退出

Q.mu = M.mu, Q.nu = N.nu, Q.tu = 0;//三元组结构类型Q存放相乘后的结果

if(M.tu * N.tu != 0)//如果两个矩阵元素相乘不为零,则进行运算

{

for(arow = 1; arow <= M.mu; ++arow)//最外侧循环以矩阵行数作为循环变量

{

for(i = 0; i <= N.nu; ++i) ctemp[i] = 0;

Q.rpos[arow] = Q.tu + 1;

if(arow < M.mu) tp = M.rpos[arow + 1];

else tp = M.tu +1;

for(p = M.rpos[arow]; p < tp; ++p)//把每行与每列相乘

{

brow = M.data[p].j;

if(brow < N.mu) t = N.rpos[brow+1];

else t = N.tu + 1;

for(q = N.rpos[brow]; q < t; ++q)

{

ccol = N.data[q].j;

ctemp[ccol] += M.data[p].e * N.data[q].e;//值相乘

}

}

for(ccol = 1; ccol <= Q.nu; ++ccol) //把运算后的结果存放到Q 中

{

if(ctemp[ccol])

{

if(++(Q.tu) > MAXSIZE) return 1;

Q.data[Q.tu].i = arow, Q.data[Q.tu].j = ccol, Q.data[Q.tu].e = ctemp[ccol];

}

}

}

}

return 1;

}//三元组相乘

3.1.5三元组的显示

void ShowTMatrix(TSMatrix M){

for(int col=1;col<=M.mu;col++)//通过双重循环,把稀疏矩阵中不为零的元素的行数、列数和值显示出来

for(int p=1;p<=M.tu;p++)

if(M.data[p].i==col)printf("%4d %4d %4d\n",M.data[p].i,M.data[p].j,M.data[p].e);

}//三元组显示

3.2.1十字链表的创建

void CreateSMatix_OL(CrossList &M){

int i,j,e;

OLink p,q;

printf("请输入稀疏矩阵的行数列数非零元素的个数:\n"); //矩阵行数,列数下标均从开始;

scanf("%d%d%d",&M.mu,&M.nu,&M.tu);

if(!(M.rhead=(OLink *)malloc((M.mu+1)*sizeof(OLNode)))) exit(1);//分配内存空间if(!(M.chead=(OLink *)malloc((M.nu+1)*sizeof(OLNode)))) exit(1);//分配内存空间for( i=1;i<=M.mu;i++)M.rhead[i]=NULL; //把矩阵

每个元素置空值

for( i=1;i<=M.nu;i++)M.chead[i]=NULL;

printf("请输入非零元素的行坐标列坐标值:");

scanf("%d%d%d",&i,&j,&e);

while(i!=0){

p=(OLink)malloc(sizeof(OLNode));

p->i=i;p->j=j;p->e=e;

if(M.rhead[i]==NULL||M.rhead[i]->j>j){p->right=M.rhead[i];M.rhead[i]=p;}

else{

q=M.rhead[i];

while(q->right&&q->right->jright;

p->right=q->right;

q->right=p;}

if(M.chead[j]==NULL||M.chead[j]->i>i){p->down=M.chead[j];M.chead[j]=p;}

else{

q=M.chead[j];

while(q->down&&q->down->idown;

p->down=q->down;

q->down=p;

}

scanf("%d%d%d",&i,&j,&e);

}

} //创建十字链表

3.2.2十字链表的显示

int ShowMAtrix(CrossList *A){

int col;

OLink p;

for(col=1;col<=A->mu;col++)if(A->rhead[col]){p=A->rhead[col];

while(p){printf("%3d%3d%3d\n",p->i,p->j,p->e);p=p->right;}

}

return 1;

} //十字链表显示

3.3 主函数

//主函数

void main(){

int n,i;

TSMatrix M,T,S;

CrossList MM,TT,SS;

printf("*******稀疏矩阵的应用*******\n");

printf("\n1:用三元组创建稀疏矩阵\n2:用十字链表创建稀疏矩阵\n3:退出程序"); printf("\n");

scanf("%d",&n);

switch(n){

case 1:

CreateSMatrix(M);

printf("您输入的稀疏矩阵为:\n 行列大小\n");

ShowTMatrix(M);

printf("已经选择三元组创建稀疏矩阵,请继续选择:\n1:稀疏矩阵转置\n2:稀疏矩阵相加\n3:稀疏矩阵相乘\n4:退出程序\n");

scanf("%d",&i);

switch(i){

case 1:TransposeSMatrix(M,T);

printf("转置后的矩阵为:\n 行列大小\n");

ShowTMatrix(T);

break;

case 2:printf("请你输入另一个稀疏矩阵:");

CreateSMatrix(T);

AddTMatix(M,T,S);

printf("相加后的矩阵为:\n 行列大小\n");

ShowTMatrix(S);

break;

case 3:printf("请你输入另一个稀疏矩阵:");

CreateSMatrix(T);

MultSMatrix(M,T,S);

printf("相乘后的矩阵为:\n 行列大小\n");

ShowTMatrix(S);

break;

case 4:

exit(0);};break;

case 2:{CreateSMatix_OL(MM);

printf("您输入的稀疏矩阵为:\n 行列大小\n");

ShowMAtrix(&MM);

printf("已经选择十字链表创建稀疏矩阵,请选择操作:\n1:稀疏矩阵转置\n2:稀疏矩阵相加\n3:稀疏矩阵相乘\n4:退出程序\n");

scanf("%d",&i);

switch(i){

case 1:

TurnSMatrix_OL(MM);

printf("转置后的矩阵为:\n 行列大小\n");

ShowMAtrix(&MM);

break;

case 2:

printf("请你输入另一个稀疏矩阵:");

CreateSMatix_OL(TT);

SMatrix_ADD(&MM,&TT);

printf("相加后的矩阵为:\n 行列大小\n");

ShowMAtrix(&MM);break;

case 3:printf("请你输入另一个稀疏矩阵:");

CreateSMatix_OL(TT);

MultSMatrix_OL(MM,TT,SS);

printf("相乘后的矩阵为:\n 行列大小\n"); ShowMAtrix(&SS);break;

case 4:exit(0);

}};break;

case 3:exit(0);

default :printf("输入错误!");

}

}

4 设计体会及结束语

通过设计本程序,加深了对矩阵存储的了解,掌握了稀疏矩阵三元组存储和十字链表存储两种存储方法。课本上介绍的较简略,有的地方甚至有个错误,经过不断检查才最终发现,发现课本上的不一定是对的,同样的问题也许有更好的方法。很多不懂的地方通过上网查资料,借鉴别人的设计经验,学习新的函数最终完成了本设计。通过这次课程设计,丰富了自己的专业知识,增强了自己解决问题的能力,有很大帮助。

完成这次设计要感谢指导老师李晓红老师,及室友们的帮助。

附1 参考文献

【1】数据结构(c语言版)严蔚敏吴伟民清华大学出版社 2007

【2】C程序设计教程张蕊吕涛华中科技大学出版社 2012.9

【3】C++面向对象程序设计教程第3版陈维兴林小茶清华大学出版社2009.6

【4】百度文库稀疏矩阵十字链表运算

附2 源代码

#include

#include

#define MAXSIZE 10000

typedef struct OLNode{

int i,j;

int e; //十字链表每个元素的行坐标,列坐标,值struct OLNode *right,*down;

}OLNode,*OLink;

typedef struct {

int mu,nu,tu; //矩阵的行数,列数,非零元个数

OLink *rhead,*chead; //行和列头指针

}CrossList; //十字链表结构体定义

typedef struct{

int i,j; //三元组每个元素的行坐标,列坐标,值

int e;

}Triple;

typedef struct{

Triple data[MAXSIZE+1];

int rpos[MAXSIZE + 1]; //三元组各行第一个元素的位置

int mu,nu,tu; //三元组矩阵的行数,列数,非零元个数

}TSMatrix; //三元组结构体定义;

void CreateSMatrix(TSMatrix &M){

//采用三元组顺序表存储表示,创建稀疏矩阵M

printf("请输入稀疏矩阵的行数列数非零元个数:\n");

scanf("%d%d%d",&M.mu,&M.nu,&M.tu);

if((M.mu<=0)||(M.nu<=0)||(M.tu<=0)||(M.tu>M.mu*M.nu))

//判断行值、列值、元素个数是否合法

printf("输入有误!");

for(int i=1;i<=M.tu;i++){ //输入稀疏矩阵元素

printf("请输入请输入非零元的行坐标列坐标值:");

scanf("%d%d%d",&M.data[i].i,&M.data[i].j,&M.data[i].e);

if((M.data[i].i<=0)||(M.data[i].j<=0)){

printf("输入错误,请重新输入!");

scanf("%d%d%d",&M.data[i].i,&M.data[i].j,&M.data[i].e);

}//if

}//for

int num[100];

if(M.tu)

{int i;

for(i = 1; i <= M.mu; i++) num[i] = 0; //初始化

for(int t = 1; t <= M.tu; t++) ++num[M.data[t].i]; //求M中每一行含非零元素个数

//求rpos

M.rpos[1] = 1;

for(i = 2; i <= M.mu; i++) M.rpos[i] = M.rpos[i-1] + num[i-1];

}

}//创建三元组

void TransposeSMatrix(TSMatrix M,TSMatrix &T){

T.nu=M.mu; //通过三元组表示,将M转置为T

T.mu=M.nu;

T.tu=M.tu;

int q=1;

for(int col=1;col<=M.nu;col++)

for(int 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++;

}

} //三元组转置

int Compare(int a1,int b1,int a2,int b2){

if(a1>a2)return 1;

else if(a1

else if(b1>b2)return 1;

if(b1

else return 0;

}

void AddTMatix(TSMatrix M,TSMatrix T,TSMatrix &S){//矩阵S存放相加后的矩阵

实现稀疏矩阵(采用三元组表示)的基本运算实验报告

实现稀疏矩阵(采用三元组表示)的基本运算实验报告 一实验题目: 实现稀疏矩阵(采用三元组表示)的基本运算二实验要求: (1)生成如下两个稀疏矩阵的三元组 a 和 b;(上机实验指导 P92 )(2)输出 a 转置矩阵的三元组; (3)输出a + b 的三元组; (4)输出 a * b 的三元组; 三实验内容: 稀疏矩阵的抽象数据类型: ADT SparseMatrix { 数据对象:D={aij| i = 1,2,3,….,m; j =1,2,3,……,n; ai,j∈ElemSet,m和n分别称为矩阵的行数和列数} 数据关系: R={ Row , Col } Row ={ | 1≤i≤m , 1≤j ≤n-1} Col ={| 1≤i≤m-1,1≤j ≤n} 基本操作:

CreateSMatrix(&M) 操作结果:创建稀疏矩阵 M PrintSMatrix(M) 初始条件:稀疏矩阵M已经存在 操作结果:打印矩阵M DestroySMatrix(&M) 初始条件:稀疏矩阵M已经存在 操作结果:销毁矩阵M CopySMatrix(M, &T) 初始条件:稀疏矩阵M已经存在 操作结果:复制矩阵M到T AddSMatrix(M, N, &Q) 初始条件:稀疏矩阵M、N已经存在 操作结果:求矩阵的和Q=M+N SubSMatrix(M, N, &Q) 初始条件:稀疏矩阵M、N已经存在 操作结果:求矩阵的差Q=M-N TransposeSMatrix(M, & T) 初始条件:稀疏矩阵M已经存在 操作结果:求矩阵M的转置T MultSMatrix(M, N, &Q) 初始条件:稀疏矩阵M已经存在

数据结构实验五矩阵的压缩存储与运算学习资料

数据结构实验五矩阵的压缩存储与运算

第五章矩阵的压缩存储与运算 【实验目的】 1. 熟练掌握稀疏矩阵的两种存储结构(三元组表和十字链表)的实现; 2. 掌握稀疏矩阵的加法、转置、乘法等基本运算; 3. 加深对线性表的顺序存储和链式结构的理解。 第一节知识准备 矩阵是由两个关系(行关系和列关系)组成的二维数组,因此对每一个关系上都可以用线性表进行处理;考虑到两个关系的先后,在存储上就有按行优先和按列优先两种存储方式,所谓按行优先,是指将矩阵的每一行看成一个元素进行存储;所谓按列优先,是指将矩阵的每一列看成一个元素进行存储;这是矩阵在计算机中用一个连续存储区域存放的一般情形,对特殊矩阵还有特殊的存储方式。 一、特殊矩阵的压缩存储 1. 对称矩阵和上、下三角阵 若n阶矩阵A中的元素满足= (0≤i,j≤n-1 )则称为n阶对称矩阵。对n阶对称矩阵,我们只需要存储下三角元素就可以了。事实上对上三角矩阵(下三角部分为零)和下三角矩阵(上三角部分为零),都可以用一维数组ma[0.. ]来存储A的下三角元素(对上三角矩阵做转置存储),称ma为矩阵A的压缩存储结构,现在我们来分析以下,A和ma之间的元素对应放置关系。 问题已经转化为:已知二维矩阵A[i,j],如图5-1, 我们将A用一个一维数组ma[k]来存储,它们之间存在着如图5-2所示的一一对应关系。 任意一组下标(i,j)都可在ma中的位置k中找到元素m[k]= ;这里: k=i(i+1)/2+j (i≥j) 图5-1 下三角矩阵 a00 a10 a11 a20 … an-1,0 … an-1,n-1

k= 0 1 2 3 …n(n- 1)/2 …n(n+1)/2-1 图5-2下三角矩阵的压缩存储 反之,对所有的k=0,1,2,…,n(n+1)/2-1,都能确定ma[k]中的元素在矩阵A中的位置(i,j)。这里,i=d-1,(d是使sum= > k的最小整数),j= 。 2. 三对角矩阵 在三对角矩阵中,所有的非零元素集中在以主对角线为中心的带内状区域中,除了主对角线上和直接在对角线上、下方对角线上的元素之外,所有其它的元素皆为零,见图5-3。 图5-3 三对角矩阵A 与下三角矩阵的存储一样,我们也可以用一个一维数组ma[0..3n-2]来存放三对角矩阵A,其对应关系见图5-4。 a00 a01 a10 a11 a12 … an-1,n-2 an-1,n-1 k= 0 1 2 3 4 … 3n-3 3n-2 图5-4下三角矩阵的压缩存储 A中的一对下标(i,j)与ma中的下标k之间有如下的关系: 公式中采用了C语言的符号,int()表示取整,‘%’表示求余。

稀疏矩阵的运算(完美版)

专业课程设计I报告(2011 / 2012 学年第二学期) 题目稀疏矩阵的转换 专业软件工程 学生姓名张鹏宇 班级学号 09003018 指导教师张卫丰 指导单位计算机学院软件工程系 日期 2012年6月18号

指导教师成绩评定表

附件: 稀疏矩阵的转换 一、课题内容和要求 1.问题描述 设计程序用十字链表实现稀疏矩阵的加、减、乘、转置。 2.需求分析 (1)设计函数建立稀疏矩阵,初始化值。 (2)设计函数输出稀疏矩阵的值。 (3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。 (4)构造函数进行两个稀疏矩阵相减,输出最终的稀疏矩阵。 (5)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。 (6)构造函数进行稀疏矩阵的转置,并输出结果。 (7)退出系统。 二、设计思路分析 (1)设计函数建立稀疏矩阵,初始化值。 (2)设计函数输出稀疏矩阵的值。 (3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。 (4)构造函数进行两个稀疏矩阵相减,输出最终的稀疏矩阵。 (5)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。 (6)构造函数进行稀疏矩阵的转置,并输出结果。 (7)退出系统。 三、概要设计 为了实现以上功能,可以从3个方面着手设计。 1.主界面设计 为了实现对稀疏矩阵的多种算法功能的管理,首先设计一个含有多个菜单项的主

控菜单子程序以链接系统的各项子功能,方便用户交互式使用本系统。本系统主控菜单运行界面如图所示。 2.存储结构设计 本系统采用单链表结构存储稀疏矩阵的具体信息。其中:全部结点的信息用头结点为指针数组的单链表存储。 3.系统功能设计 本系统除了要完成稀疏矩阵的初始化功能外还设置了4个子功能菜单。稀疏矩阵的初始化由函数i typedef int ElemType 实现。建立稀疏矩阵用void Creat()实现,依据读入的行数和列数以及非零元素的个数,分别设定每个非零元素的信息。4个子功能的设计描述如下。 (1)稀疏矩阵的加法: 此功能由函数void Xiangjia( )实现,当用户选择该功能,系统即提示用户初始化要进行加法的两个矩阵的信息。然后进行加法,最后输出结果。 (2)稀疏矩阵的乘法: 此功能由函数void Xiangcheng( )实现。当用户选择该功能,系统提示输

三角矩阵在压缩存储下的转置矩阵源代码

#include #include #define max 20 #define zero 0 typedef struct{ int i,j,v; }node; typedef struct{ node data[max]; int m; }TSmatrix; TSmatrix *Setmatrix(){ //建三对角矩阵TSmatrix *T; T=(TSmatrix *)malloc(sizeof(TSmatrix)); printf("请输入矩阵行数或列数:\n"); scanf("%d",&T->m); printf("建立三对角矩阵:\n"); for(int n=0;n<3*T->m-2;n++) scanf("%d%d%d",&T->data[n].i,&T->dat a[n].j,&T->data[n].v); return T; } TSmatrix *Trabsmatrix(TSmatrix *T){ //三对角矩阵转置 int n,k,temp; TSmatrix *F; F=(TSmatrix *)malloc(sizeof(TSmatrix)); F->m=T->m; for(n=0;n<3*T->m-2;n++){ //将结点信息存入新三元组表中 temp=2*T->data[n].j+T->data[n].i; //计算待存入三元数组下标 F->data[temp].i=T->data[n].j; F->data[temp].j=T->data[n].i; F->data[temp].v=T->data[n].v; } return F; } void TSmatrixout(TSmatrix *T){ //三对角矩阵输出 int a,b,n; n=0; for(a=0;am;a++){ for(b=0;bm;b++){ if(T->data[n].i==a&&T->data[n].j==b){ printf("%-5d",T->data[n].v); n++; } else printf("%-5d",zero); } printf("\n"); } } void main(){ TSmatrix *T; T=Setmatrix(); printf("三对角矩阵:\n"); TSmatrixout(T); T=Trabsmatrix(T); printf("转置后三对角矩阵:\n"); TSmatrixout(T); } 问题分析: 本程序要求实现对压缩存储下的三对角矩阵进行转置,为实现上述功能,需要解决的关键问题是三对角矩阵压缩存储及转置过程。 概要设计: 利用三元组表以行序为主序压缩存储三对角矩阵。转置时,先利用三元数组中的行标i 和列标j计算出待放入新三元数组的下标temp。由于转置时需要将行标和列标交换,所以temp=2*j+i。找出待存入的下标后,将相应的信息存入下标为temp的三元数组中。 详细设计:

稀疏矩阵及其压缩存储方法

稀疏矩阵及其压缩存储方法 1.基本概念 稀疏矩阵(SparseMatrix):是矩阵中的一种特殊情况,其非零元素的个数远小于零元素的个数。 设m行n列的矩阵含t个非零元素,则称 以二维数组表示高阶的稀疏矩阵时,会产生零值元素占的空间很大且进行了很多和零值的运算的问题。 特殊矩阵:值相同的元素或0元素在矩阵中的分布有一定的规律。如下三角阵、三对角阵、稀疏矩阵。 压缩存储:为多个值相同的元素只分配一个存储空间;对0元素不分配空间。目的是节省大量存储空间。 n x n的矩阵一般需要n2个存储单元,当为对称矩阵时需要n(1+n)/2个单元。 2.三元组顺序表——压缩存储稀疏矩阵方法之一(顺序存储结构) 三元组顺序表又称有序的双下标法,对矩阵中的每个非零元素用三个域分别表示其所在的行号、列号和元素值。它的特点是,非零元在表中按行序有序存储,因此便于进行依行顺序处理的矩阵运算。当矩阵中的非0元素少于1/3时即可节省存储空间。 (1)稀疏矩阵的三元组顺序表存储表示方法 #define MAXSIZE 12500 // 假设非零元个数的最大值为12500 typedef struct { int i, j; // 该非零元的行下标和列下标 ElemType e; //非零元素的值 } Triple; // 三元组类型 typedef union { //共用体 Triple data[MAXSIZE + 1]; // 非零元三元组表,data[0]未用 int mu, nu, tu; // 矩阵的行数、列数和非零元个数 } TSMatrix; // 稀疏矩阵类型 (2)求转置矩阵的操作 ◆用常规的二维数组表示时的算法 for (col=1; col<=nu; ++col) for (row=1; row<=mu; ++row) T[col][row] = M[row][col]; 其时间复杂度为: O(mu×nu) ◆用三元组顺序表表示时的快速转置算法 Status FastTransposeSMatrix(TSMatrix M, TSMatrix &T) { // 采用三元组顺序表存储表示,求稀疏矩阵M的转置矩阵T 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 中每一列所含非零元的个数

稀疏矩阵基本操作 实验报告

稀疏矩阵基本操作实验报告 一、实验内容 稀疏矩阵的压缩储存结构,以及稀疏矩阵的三元组表表示方法下的转置、相加、相乘等算法 二、实验目的 1.熟悉数组、矩阵的定义和基本操作 2.熟悉稀疏矩阵的储存方式和基本运算 3.理解稀疏矩阵的三元组表类型定义,掌握稀疏矩阵的输入、输出和转置算法 三、实验原理 1.使用三元组储存矩阵中的非零元素(三元组分别储存非零元素的行下标,列下标和 元素值)。除了三元组表本身,储存一个稀疏矩阵还需要额外的三个变量,分别储存矩阵的非零元个数,矩阵的行数和矩阵的列数。 2.稀疏矩阵的创建算法: 第一步:根据矩阵创建一个二维数组,表示原始矩阵 第二步:取出二维数组中的元素(从第一个元素开始取),判断取出元素是否为非零元素,如果为非零元素,把该非零元素的数值以及行下标和列下表储存到三元数组表里,否则取出下一个元素,重复该步骤。 第三步:重复第二步,知道二维数组中所有的元素已经取出。 3.稀疏矩阵倒置算法: 第一步:判断进行倒置的矩阵是否为空矩阵,如果是,则直接返回错误信息。 第二步:计算要倒置的矩阵每列非零元素的数量,存入到num数组(其中num[i] 代表矩阵中第i列非零元素的个数)。以及倒置后矩阵每行首非零元的位置,存入cpot 数组中(其中cpot表示倒置后矩阵每行非零元的位置,对应表示原矩阵每列中第一个非零元的位置)。 第三步:确定倒置后矩阵的行数和列数。 第四步:取出表示要导致矩阵中三元组表元素{e, I, j}(第一次取出第一个,依次取出下一个元素),从第二步cpot数组中确定该元素倒置后存放的位置(cpot[j]),把该元素的行下标和列下标倒置以后放入新表的指定位置中。cpot[j] 变量加一。 第五步:重复第四步,直到三元组表中所有的元素都完成倒置。 第六步:把完成倒置运算的三元组表输出。 4.稀疏矩阵加法算法: 第一步:检查相加两个矩阵的行数和列数是否相同,如果相同,则进入第二步,否则输出错误信息。 第二步:定义变量i和j,用于控制三元组表的遍历。 第三步:比较变量矩阵M中第i个元素和矩阵N中第j个元素,如果两个元素是同一行元素,如果不是则进入第四步,如果是,再继续比较两个元素是否为同一列元素,如果是,把两个元素值相加,放到三元组表中;否则把列下表小的元素依次放到三元组表中。进入第五步 第四步:如果矩阵M中第i个元素的行下标大于矩阵N中第j个元素的行下标,则把矩阵N中第j个元素所在行的所有非零元素添加到三元组表中;如果矩阵M中第

稀疏矩阵的运算(完美版)

专业课程设计I报告( 2011 / 2012 学年第二学期) 题目稀疏矩阵的转换 专业软件工程 学生姓名张鹏宇 班级学号 09003018 指导教师张卫丰 指导单位计算机学院软件工程系 日期 2012年6月18号

指导教师成绩评定表

附件: 稀疏矩阵的转换 一、课题内容和要求 1.问题描述 设计程序用十字链表实现稀疏矩阵的加、减、乘、转置。 2.需求分析 (1)设计函数建立稀疏矩阵,初始化值。 (2)设计函数输出稀疏矩阵的值。 (3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。 (4)构造函数进行两个稀疏矩阵相减,输出最终的稀疏矩阵。 (5)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。 (6)构造函数进行稀疏矩阵的转置,并输出结果。 (7)退出系统。 二、设计思路分析 (1)设计函数建立稀疏矩阵,初始化值。 (2)设计函数输出稀疏矩阵的值。 (3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。 (4)构造函数进行两个稀疏矩阵相减,输出最终的稀疏矩阵。 (5)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。 (6)构造函数进行稀疏矩阵的转置,并输出结果。 (7)退出系统。 三、概要设计 为了实现以上功能,可以从3个方面着手设计。 1.主界面设计 为了实现对稀疏矩阵的多种算法功能的管理,首先设计一个含有多个菜单项的主控菜单子程序以链接系统的各项子功能,方便用户交互式使用本系统。本系统主控菜单运行界面如图所示。

2.存储结构设计 本系统采用单链表结构存储稀疏矩阵的具体信息。其中:全部结点的信息用头结点为指针数组的单链表存储。 3.系统功能设计 本系统除了要完成稀疏矩阵的初始化功能外还设置了4个子功能菜单。稀疏矩阵的初始化由函数i typedef int ElemType 实现。建立稀疏矩阵用void Creat()实现,依据读入的行数和列数以及非零元素的个数,分别设定每个非零元素的信息。4个子功能的设计描述如下。 (1)稀疏矩阵的加法: 此功能由函数void Xiangjia( )实现,当用户选择该功能,系统即提示用户初始化要进行加法的两个矩阵的信息。然后进行加法,最后输出结果。 (2)稀疏矩阵的乘法: 此功能由函数void Xiangcheng( )实现。当用户选择该功能,系统提示输入要进行相乘的两个矩阵的详细信息。然后进行相乘,最后得到结果。 (3)稀疏矩阵的转置: 此功能由函数void Zhuanzhi( )实现。当用户选择该功能,系统提示用户初始

数据结构实验五矩阵的压缩存储与运算

第五章矩阵的压缩存储与运算 【实验目的】 1. 熟练掌握稀疏矩阵的两种存储结构(三元组表和十字链表)的实现; 2. 掌握稀疏矩阵的加法、转置、乘法等基本运算; 3. 加深对线性表的顺序存储和链式结构的理解。 第一节知识准备 矩阵是由两个关系(行关系和列关系)组成的二维数组,因此对每一个关系上都可以用线性表进行处理;考虑到两个关系的先后,在存储上就有按行优先和按列优先两种存储方式,所谓按行优先,是指将矩阵的每一行看成一个元素进行存储;所谓按列优先,是指将矩阵的每一列看成一个元素进行存储;这是矩阵在计算机中用一个连续存储区域存放的一般情形,对特殊矩阵还有特殊的存储方式。 一、特殊矩阵的压缩存储 1. 对称矩阵和上、下三角阵 若n阶矩阵A中的元素满足 = (0≤i,j≤n-1 )则称为n阶对称矩阵。对n阶对称矩阵,我们只需要存储下三角元素就可以了。事实上对上三角矩阵(下三角部分为零)和下三角矩阵(上三角部分为零),都可以用一维数组ma[0.. ]来存储A的下三角元素(对上三角矩阵做转置存储),称ma为矩阵A的压缩存储结构,现在我们来分析以下,A和ma之间的元素对应放置关系。 问题已经转化为:已知二维矩阵A[i,j],如图5-1, 我们将A用一个一维数组ma[k]来存储,它们之间存在着如图5-2所示的一一对应关系。 任意一组下标(i,j)都可在ma中的位置k中找到元素m[k]= ;这里: k=i(i+1)/2+j (i≥j) 图5-1 下三角矩阵 a00 a10 a11 a20 … an-1,0 … an-1,n-1 k= 0 1 2 3 … n(n-1)/2 … n(n+1)/2-1 图5-2下三角矩阵的压缩存储 反之,对所有的k=0,1,2,…,n(n+1)/2-1,都能确定ma[k]中的元素在矩阵A中的位置(i,j)。这里,i=d-1,(d是使sum= > k的最小整数),j= 。 2. 三对角矩阵

稀疏矩阵乘法的运算

课程设计任务书 学生姓名:专业班级: 指导教师:夏红霞工作单位:计算机科学与技术学院题目: 稀疏矩阵乘法的运算 课程设计要求: 1、熟练掌握基本的数据结构; 2、熟练掌握各种算法; 3、运用高级语言编写质量高、风格好的应用程序。 课程设计任务: 1、系统应具备的功能: (1)设计稀疏矩阵的存储结构 (2)建立稀疏矩阵 (3)实现稀疏矩阵的乘法 2、数据结构设计; 3、主要算法设计; 4、编程及上机实现; 5、撰写课程设计报告,包括: (1)设计题目; (2)摘要和关键字; (3)正文,包括引言、需求分析、数据结构设计、算法设计、程序实现及测试、不足之处、设计体会等; (4)结束语; (5)参考文献。 时间安排:2010年7月5日-9日(第19周) 7月5日查阅资料 7月6日系统设计,数据结构设计,算法设计 7月7日 -8日编程并上机调试 7月9日撰写报告 7月10日验收程序,提交设计报告书。 指导教师签名: 2010年7月4日系主任(或责任教师)签名: 2010年7月4日

目录 1.摘要 (1) 2.关键字 (1) 3.引言 (1) 4. 问题描述 (1) 5. 系统设计 (1) 6. 数据结构 (3) 7. 算法描述 (3) 8. 测试结果与分析 (4) 9. 源代码 (12) 10. 总结 (29) 11.参考文献 (29)

稀疏矩阵乘法的运算 1.摘要:在一些数值计算中,一些二维矩阵的乘法运算很常见,我们经常采用线性代数中的知识进行运算,然而对一些含有非零元很少的二维矩阵也采用相同的方法时,就会发现那样的方法不仅需要很多的空间来存储0,造成空间复杂度比较大,而且算法的时间复杂度也较大。因此需要采取其他的方法来解决这个问题,由于0在乘法中其结果总是0,所以可以考虑采用三元组的方式去存储稀疏矩阵中的非零元,这样在计算过程中不仅需要的内存空间减少了,而且运算的速率也提高了。 2.关键字:稀疏矩阵乘法二维矩阵算法复杂度 3.引言:随着科学技术的发展,人们对矩阵的运算的几率越来越大,特别是高新科技研究中对矩阵的运算更是常见。但是如何高效的并占内存少的进行矩阵运算就是一个急需解决的问题。本文主要对稀疏矩阵的存储以及稀疏矩阵的乘法运算进行了研究和探讨。 4.问题描述:在一些数值计算中,一些二维矩阵的乘法运算很常见,我们经常采用线性代数中的知识进行运算,然而对一些含有非零元很少的二维矩阵也采用相同的方法时,就会发现那样的方法不仅需要很多的空间来存储0,造成空间复杂度比较大,而且算法的时间复杂度也较大。为了减少空间和时间复杂度,可以根据给定的二维数组的数据设计稀疏矩阵的存储结构,然后根据设计的稀疏矩阵存储结构建立一个稀疏矩阵,最后获得两个二维数组得到他们各自的稀疏矩阵,计算这两个稀疏矩阵的乘积。 5.系统设计: 5.1 设计目标:通过一定的数据结构,存储含有少量数据的矩阵,把他们存入一个稀疏矩阵中,然后实现稀疏矩阵的乘法运算。[基本要求]设计稀疏矩阵的存储结构;建立稀疏矩阵;实现稀疏矩阵的乘法

稀疏矩阵乘法运算

稀疏矩阵的乘法运算 程序代码: #include #include #include #include #include #include #define Ture 1 #define Overflow -1 typedef struct OLnode { int i,j; int e; struct OLnode *right,*down; }OLnode,*Olink; typedef struct { Olink *rhead,*chead; int mu,nu,tu; }Crosslist; //在十字链表M.rhead[row]中插入一个t结点

void insert_row(Crosslist &M,OLnode *t,int row) { OLnode *p; int col=t->j; if(M.rhead[row]==NULL||M.rhead[row]->j>col) { t->right=M.rhead[row]; M.rhead[row]=t; } else { for(p=M.rhead[row];p->right&&p->right->jright);//寻找在行表中的插入位置 t->right=p->right; p->right=t; } } //在十字链表M.chead[col]中插入一个结点t void insert_col(Crosslist &M,OLnode *t,int col) { OLnode *p; int row=t->i; if(M.chead[col]==NULL||M.chead[col]->i>row) { t->down=M.chead[col];

压缩矩阵的运算

实验四数组的运算 实验目的: 掌握稀疏矩阵的压缩存储方法及主要运算的实现。 实验内容与要求: 设计一个稀疏矩阵计算器,要求能够:⑴输入并建立稀疏矩阵;⑵输出稀疏矩阵;⑶执行两个矩阵相加;⑷执行两个矩阵相乘;⑸求一个矩阵的转置矩阵;⑹求一个矩阵的逆矩阵(选做)。 实验代码: Rect.h #define MAXSIZE100 typedef struct { int h_num; int v_num; int elem; }Triple; typedef struct { Triple *arry; int h_i; int v_j; int elem_num; }TSMatrix; void Init_TS(TSMatrix *T ); void creat(TSMatrix *T); void Print_TS(TSMatrix *); void sum_TS(TSMatrix *T1,TSMatrix *T2,TSMatrix *T); void mul_TS(TSMatrix *T1,TSMatrix *T2,TSMatrix *T); void transpose_TS(TSMatrix *T); void equal_Triple(Triple *t1,Triple *t2); Rect.cpp #include #include #include"rect.h"

void Init_TS(TSMatrix *T) { T->arry=(Triple *)malloc(MAXSIZE*sizeof(Triple)); if(!T->arry) printf("error\n") ; T->elem_num=0; T->h_i=0; T->v_j=0; } void Init_Tr(Triple *t) { t->elem=0; t->h_num=0; t->v_num=0; } void creat(TSMatrix *T) { printf("要输入的数组的行数和列数\n"); scanf("%d,%d",&T->h_i,&T->v_j); printf("要输入稀疏数组的元素个数\n"); scanf("%d",&T->elem_num); printf("输入要输入的稀疏数组的信息\n"); printf("行值列值元素值\n"); for(int i=0;ielem_num;i++) { scanf("%d %d %d",&T->arry[i].h_num,&T->arry[i].v_num,&T->arry[i].elem); } }; void Print_TS(TSMatrix *T) { printf("输出稀疏数组的信息\n"); printf("行下标列下标元素值\n"); for(int i=0;ielem_num;i++) { printf("%d %d %d\n",T->arry[i].h_num,T->arry[i].v_num,T->arry[i].elem); } }; void sum_TS(TSMatrix *T1,TSMatrix *T2,TSMatrix *T) { T->h_i=T1->h_i;T->v_j=T1->v_j;

稀疏矩阵的运算

数据结构课程设计稀疏矩阵的运算 学生姓名: 学号: 指导教师: 完成日期:

目录: 1、分析问题和确定解决方案 (3) 1.1问题描述 (3) 1.2 输入的形式和输入值的范围 (3) 1.3 输出的形式 (3) 1.4 程序所能达到的功能 (3) 1.5 测试数据 (3) 1.6 确定解决方案 (4) 1.7所有抽象数据类型的定义 (4) 2、详细设计 (5) 2.1稀疏矩阵加法运算思路 (5) 2.2稀疏矩阵减法运算思路 (7) 2.3稀疏矩阵转置运算思路 (9) 2.4创建稀疏矩阵 (11) 3、系统调试与测试 (12) 3.1程序的菜单界面 (12) 3.2 实现加法运算 (12) 3.3 实现减法运算 (13) 3.4实现转置运算 (14) 4、结果分析 (15) 4.1、算法的时空分析 (15) 4.2、经验和体会 (15) 5、参考文献 (15)

1、分析问题和确定解决方案 1.1问题描述 稀疏矩阵是指那些多数元素为零的矩阵。利用“稀疏”特点进行存储和计 算可以大大节省存储空间,提高计算效率。实现一个能进行稀疏矩阵基本运算的运算器。用三元组实现稀疏矩阵的相加、相减,转置; 1.2输入的形式和输入值的范围 以三元组的形式输入,首先应输入矩阵的行数和列数,并判别给出的两个 矩阵的行、列数对于所要求作的运算是否相匹配。可设矩阵的行数和列数均不超过20; 例如:输入的三元组为:((1,1,10),(2,3,9),(3,1,-1))其对应的稀疏矩阵为: ???? ??????-0019000010 1.3 输出的形式 运算结果的矩阵以通常的阵列形式输出; 1.4程序所能达到的功能 该程序可以实现以三元组形式输入两个矩阵,求出两个矩阵的和、差、转置; 并可根据输入的矩阵的行列数不同判别是否可以进行相加、减、转置,并重新输 入正确的矩阵; 1.5测试数据 测试的数据及其结果如下: 矩阵M 矩阵N 矩阵Q 加法: ???? ??????-0019000010 + ????? ?????--301100000 = ????? ?????-3008000010 减法: ???? ? ?????-0190010 - ???? ? ?????--311000 = ???? ??????-32100010 转置:

稀疏矩阵的压缩存储上

第3讲 稀疏矩阵压缩存储上——教学讲义 稀疏矩阵是指矩阵中大多数元素为零的矩阵。从直观上讲,当非零元素个数低于总元素的30 %时,这样的矩阵为稀疏矩阵。如下图所示的矩阵M 、 N 中,非零元素个数均为8个,矩阵元素总数均为6 ×7 =42 ,显然8 /42 <30 %,所以M 、 N 都是稀疏矩阵。 1 稀疏矩阵的三元组表表示法 ( 1 ) 稀疏矩阵的三元组存储表示 对于稀疏矩阵的压缩存储,采取只存储非零元素的方法。由于稀疏矩阵中非零元素aij 的分布没有规律 ,因此,要求在存储非零元素值的同时还必须存储该非零元素在矩阵中所处的行号和列号的位置信息,这就是稀疏矩阵的三元组表表示法。 每个非零元素在一维数组中的表示形式如下图所示。 说明:为处理方便,将稀疏矩阵中非零元素对应的三元组按“行序为主序”用一维结构体数组进行存放,将矩阵的每一行(行由小到大)的全部非零元素的三元组按列号递增存放。由此得到矩阵M 、 N 的三元组表A 和B 。如下图所示。 0 12 9 0 0 0 0 0 0 0 0 0 0 0 -3 0 0 0 0 14 0 0 0 24 0 0 0 0 0 18 0 0 0 0 0 15 0 0 -7 0 0 0 M= 6×7 0 0 -3 0 0 15 12 0 0 0 18 0 9 0 0 24 0 0 0 0 0 0 0 -7 0 0 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 7×6 N= 稀疏矩阵M 和N 三元组的结构

( 2 )稀疏矩阵三元组表的类型定义 稀疏矩阵三元组表类型定义如下: #define MAXSIZE 1000 /*设非零元素的个数最多为1000*/ typedef struct { int row, col; /*该非零元素的行下标和列下标*/ ElementType e ; /*该非零元素的值*/ }Triple; typedef struct { Triple data[MAXSIZE+1]; /* 非零元素的三元组表。data[0]未用*/ int m, n, len; /*矩阵的行数、列数和非零元素的个数*/ }TSMatrix ; 在稀疏矩阵情况下,采用三元组表表示法大量节约了存储空间,以图5.10中的M 6*7矩阵为例,需要6*7=42个存储单元,但M 采用三元组表A 存放,共有8个非零元素,每个非零元按占3个单元计算,需要3*8=24个单元,显然比矩阵常规存储来讲还是大大节省存储。 ( 3 )三元组表实现稀疏矩阵的转置运算 需要强调的是,矩阵常规存储是二维的,而三元组存储是一维的,由于矩阵存储结构的变化也带来了运算方法的不同,必需认真分析。下面给出稀疏矩阵的转置运算问题,希望从中体会实现算法的处理思路和改进算法的技术。 矩阵转置指变换元素的位置,把位于( row,col)位置上的元素换到( col,row)位置上,把元素的行列互换。如图5 .10的6 ×7矩阵M,它的转置矩阵就是7×6的矩阵N,并且N( row,col)= M( col,row),其中,1 ≤ row ≤ 7 ,1 ≤ col ≤ 6 。 ①矩阵转置的经典算法 采用矩阵的正常存储方式(二维数组)实现矩阵转置。 稀疏矩阵转置经典算法 void TransMatrix (ElementType source[m][n], ElementType dest[n][m]) {/*source 和dest 分别为被转置的矩阵和转置以后的矩阵(用二维数组表示)*/ int i, j; for(i=0;i

稀疏矩阵的压缩存储方法及主要运算的实现

1.实验目的: 掌握稀疏矩阵的压缩存储方法及主要运算的实现。 2.实验内容与要求: 设计一个稀疏矩阵计算器,要求能够:⑴输入并建立稀疏矩阵;⑵输出稀疏矩阵;⑶执行两个矩阵相加;⑷执行两个矩阵相乘;⑸求一个矩阵的转置矩阵。 3.数据结构设计 逻辑结构:线性结构 存储结构:顺序存储结构 4.算法设计 #include #define MAXSIZE 100 typedef int datatype; typedef struct { int i,j; datatype v; }Triple; typedef struct { Triple data[MAXSIZE+1]; int rpos[MAXSIZE+1]; int mu,nu,tu; }RLSMatrix; int main() { void AddSMatrix(RLSMatrix M); void MultSMatrix(RLSMatrix M); void FastTransposeSMatrix(RLSMatrix M); RLSMatrix M; int k; printf("请输入稀疏矩阵M的行数、列数和非零元素个数:"); scanf("%d%d%d",&M.mu,&M.nu,&M.tu); printf("请输入稀疏矩阵M中非零元素的行号、列号和元素的值:\n"); for(k=1;k<=M.tu;k++) scanf("%d%d%d",&M.data[k].i,&M.data[k].j,&M.data[k].v); printf("请输出稀疏矩阵M中非零元素的行号、列号和元素的值:\n"); for(k=1;k<=M.tu;k++) { printf("%d%3d%3d",M.data[k].i,M.data[k].j,M.data[k].v); printf("\n"); } AddSMatrix(M); MultSMatrix(M); FastTransposeSMatrix(M); return 0; } void AddSMatrix(RLSMatrix M) { RLSMatrix N,R;

稀疏矩阵相乘

稀疏矩阵相乘 1问题描述 1.1稀疏矩阵的三元组及十字链表表示 (1)稀疏矩阵及其三元组表示 稀疏矩阵 (2)稀疏矩阵的十字链表表示 1.2基本要求 (1)以“带行逻辑链接信息”的三元组表示稀疏矩阵; (2)输入矩阵用三元组顺序输入; (2)稀疏矩阵采用十字链表表示; (3)实现两个矩阵相乘的运算,而运算结果的矩阵则以通常的阵列形式列出。 行(row) 列(col) 值(value) [0] 0 3 22 [1] 0 6 15 [2] 1 1 11 [3] 1 5 17 [4] 2 3 -6 [5] 3 5 39 [6] 4 0 39 [7] 5 2 28 0000280 000000091039000000006000017000110150022000?????? ? ? ? ? ? ?-

2设计思路 2.1存储结构设计 2.1.1三元组表示稀疏矩阵 只存储矩阵中极少的非零元素,采用来唯一地确定每一个非零元素,其中row、col、value分别表示非零元素在矩阵中的的行下标、列下表和值。各数组元素的三元组按在原矩阵中的位置以行优先的顺序依次存放。 struct triple { //三元组结构定义 int row, col; //非零元素行号,列号 Float value; //非零元素的值 triple& operator=(triple &x) {row=x.row;col=x.col;value=x.value;} }; 2.1.2十字链表表示稀疏矩阵 struct element{ int row,col;float value;}; class Matrix; class node { // 矩阵节点类的定义 friend class Matrix; public: node():head(true){ right=down=this;} //建立附加头结点 node(element *t) // 建立非零元素结点 { triple.col=t->col; triple.row=t->row; triple.value=t->value; right=down=this; head=false;

稀疏矩阵的乘法实现

稀疏矩阵的乘法实现 程序: 1# include 2# include 3# define NULL 0 4# define OK 1 5# define ERROR 0 6# define MAXSIZE 100 /* 矩阵中非零元的最大值 */ 7# define MAXRC 10 /* 矩阵的最大行值 */ 8 9typedef int status ; 10 11 /********** 稀疏矩阵的行逻辑链接的顺序表存储表示 **********/ 12 13typedef struct /* 非零元的三元组 */ 14{ 15int i, j ; /* 非零元的行下标和列下标 */ 16int e ; 17}Triple; 18 19typedef struct /* 稀疏矩阵的行逻辑链接的顺序表 */ 20{ 21 Triple data[MAXSIZE+1]; /* 非零三元组表,data[0] 未用,以下定义的数组都是从1开始 */ 22int rpos[MAXRC+1]; /* 代表各行第一个非零元的序号表,其值为data的下标 */ 23int mu,nu,tu; /* 矩阵的行数、列数、非零元的个数 */

24}RLSMatrix; /* R:row L:logic S:sequence */ 25 26 27 /********* 基本操作的函数原型的声明 *********/ 28 29status CreateSMatrix_RL(RLSMatrix * matrix); 30// 创建一个稀疏矩阵; 31// 输入行数、列数,支持乱序输入三元组,并计数; 32// 以行为主序进行重新排列,并记录每行起始位置于 matrix->rpos[row]; 33// 若非零元超过 MAXSIZE或行数超过MAXRC,则返回ERROR,否则OK; 34 35void PrintSMatrix_RL(RLSMatrix * matrix); 36// 输入矩阵,打印出矩阵的行数、列数、非零元个数,以及整个矩阵; 37 38status MultSMatrix_RL(RLSMatrix * M,RLSMatrix * N,RLSMatrix * Q); 39// 输入两个稀疏矩阵M和N,并初始化Q,然后计算M*N的值赋给Q; 40// 如果M->mu!=N->nu或列数大于MAXRC或者计算出的非零元个数大于MAXSIZE,都返回ERROR,否则OK; 41// 计算过程如下: 42// 1. 由于矩阵M和Q的行数相等并且C语言以行为主序进行存储,所以以M进行逐行的扫描。 43// 2. 使Q的此行逻辑表的序号等于其非零元个数Q.tu+1,以表示其行的首个元素的序号。

稀疏矩阵的加法,三元组实现矩阵的乘法

#include #include 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 mu,nu,tu; }TSMatrix; typedef struct { // 定义带链接信息的三元组对象 Triple data[MAXSIZE+2]; int rpos[MAXROW+1]; int mu,nu,tu; }RLSMatrix; template bool InPutTSMatrix(P & T,int y){ //输入矩阵,按三元组格式输入cout<<"输入矩阵的行,列和非零元素个数:"<>T.mu>>T.nu>>T.tu; cout<<"请输出非零元素的位置和值:"<>T.data[k].i>>T.data[k].j>>T.data[k].e; return true; } template

bool OutPutSMatrix(P T){ // 输出矩阵,按标准格式输出 int m,n,k=1; for(m=0;m

相关主题