数据结构实验报告(实验五 稀疏矩阵运算器)
稀疏矩阵运算器实验报告
Qh=Qe=Q.data; // Qh、Qe的初值指向矩阵Q的非零元素首地址的前一地址
while(Mp<=Me&&Np<=Ne)
{
Qe++;
switch(comp(Mp->i,Np->i))
{
case 1: *Qe=*Mp;
Mp++;
while(Mp<=Me)
{
Qe++;
*Qe=*Mp;
Mp++;
}
Q.tu=Qe-Qh; //矩阵Q的非零元素个数
return 1;
}
int MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q) {
//求矩阵乘积Q=M?N,采用行逻辑链接存储表示。
int arow,brow,p,q,t,ctemp[30],l,ccol,tp;
稀疏矩阵运算器
一:问题描述:
稀疏矩阵是指那些多数元素为零的矩阵。利用稀疏特点进行储存和计算可以大大节省储存空间,提高计算效率。实现一个能进行称稀疏矩阵基本运算的运算器。
基本要求:
以带逻辑链接信息的三元组顺序表表示稀疏矩阵,实现矩阵相加,相减,相乘的运算。稀疏矩阵的输入形式采用三元组表示。而运算结果的矩阵则用通常的阵列形式列出。
else t = N.tu+1;
for (q=N.rpos[brow]; q< t; ++q) {
ccol = N.data[q].j; //乘积元素在Q中列号
ctemp[ccol] += M.data[p].e * N.data[q].e;
稀疏矩阵(实验报告)
《数据结构课程设计》实验报告一、实验目的:理解稀疏矩阵的加法运算,掌握稀疏矩阵的存储方法,即顺序存储的方式,利用顺序存储的特点——每一个元素都有一个直接前驱和一个直接后继,完成相关的操作。
二、内容与设计思想:1、设计思想1)主界面的设计定义两个矩阵a= 0 0 3 0 0 0 0 0 b= 0 2 0 0 0 0 0 00 0 0 0 0 0 5 0 0 0 0 4 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 6 0 00 0 0 0 7 0 0 0 0 0 0 0 8 0 0 00 0 0 0 0 0 0 0 0 0 1 0 0 0 0 00 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0定义两个数组A和B,用于存储矩阵a和矩阵b的值;定义一个数组C,用于存放数组A 和数组B相加后的结果。
2)实现方式稀疏矩阵的存储比较浪费空间,所以我们可以定义两个数组A、B,采用压缩存储的方式来对上面的两个矩阵进行存储。
具体的方法是,将非零元素的值和它所在的行号、列号作为一个结点存放在一起,这就唯一确定一个非零元素的三元组(i、j、v)。
将表示稀疏矩阵的非零元素的三元组按行优先的顺序排列,则得到一个其结点均为三元组的线性表。
即:以一维数组顺序存放非零元素的行号、列号和数值,行号-1作为结束标志。
例如,上面的矩阵a,利用数组A存储后内容为:A[0]=0,A[1]=2, A[2]=3, A[3]=1, A[4]=6, A[5]=5, A[6]=3, A[7]=4, A[8]=7, A[9]=5, A[10]=1, A[11]=9, A[12]=-1同理,用数组B存储矩阵b的值。
2、主要数据结构稀疏矩阵的转存算法:void CreateMatrix(int A[m][n],int B[50]){int i,j,k=0;for(i=0;i<m;i++)for(j=0;j<n;j++)if(A[i][j]!=0){B[k]=i;k++;B[k]=j;k++;B[k]=A[i][j];k++;}B[k]=-1;}稀疏矩阵的加法实现:3、主要算法结构分析:1)void CreateMatrix(int A[m][n],int B[50]),这是一个将稀疏矩阵转存的函数,类似于顺序存储三元组表。
数据结构课程设计五基本稀疏矩阵运算的运算器
数据结构课程设计五····题目:严蔚敏习题实习4第1个:实现一个能进行基本稀疏矩阵运算的运算器一、需求分析1、本程序实现一个基本稀疏矩阵的简单运算,包括加、减、乘。
2、执行操作前应先创造要进行运算的两个矩阵,然后再选择进行相应的操作。
3、以三元组顺序表表示稀疏矩阵,实现二个矩阵相加,相减,相乘的运算;稀疏矩阵的输入形式为三元组表示,运算结果则为通常的阵列形式列出!4、首先输入矩阵的行数和列数,并判别给出的两个矩阵和行、列数对于所要求作的运算是否相匹配。
可设矩阵的行数和列数均不超过20;5、程序先给出了菜单项,用户只需按照菜单提示进行相应的操作就行了。
6、测试数据:二、概要设计1、抽象数据类型三元组的定义如下:ADT Triple{数据对象:D={ai| ai(-ElemSet,i=1,2,...,n,n>=0};数据关系:R1={<ai-1,ai>| ai-1,ai(- D,i=2,...,n}基本操作:略}2、基于三元组顺序表表示的矩阵操作:(1)创建三元组顺序表表示的矩阵:void createMatrix(TSMatrix &A)(2)初始化矩阵:void initMatrix(TSMatrix &A)(3)相加:void add(TSMatrix A,TSMatrix B,TSMatrix &C)(4)相减:void sub(TSMatrix A,TSMatrix &B,TSMatrix &C)(5)找m行n列元素在A中顺序表中的位置:int search(TSMatrix A,int m,int n)(6)相乘;void mult(TSMatrix A,TSMatrix B,TSMatrix &C) (7)输入以阵列形式表示的矩阵:void print(TSMatrix A) 3、主程序Void main(){While(true){调用相应函数执行相应操作;输出操作结果;}}4、本程序只有两个模块,调用关系简单:三、详细设计1、三元组结构描述:#define MAXSIZE 20using namespace std;typedef struct{int row;int col;int e;}Triple;typedef struct{Triple date[MAXSIZE];int m,n,len;}TSMatrix;void initMatrix(TSMatrix &A){A.len=0;A.m=0;for(int i=0;i<MAXSIZE;i++){A.date[i].col=0;A.date[i].e=0;A.date[i].row=0;}}2、各种操作函数源代码:void createMatrix(TSMatrix &A){initMatrix(A);cout<<"创建矩阵:";cout<<"请输入矩阵的行列值及非0元素个数\n";cin>>A.m>>A.n>>A.len;for(int i=0;i<A.len;i++){cout<<"请输入第"<<i<<"个非0元素对应的行、列、值:";cin>>A.date[i].row;cin>>A.date[i].col;cin>>A.date[i].e;}}void add(TSMatrix A,TSMatrix B,TSMatrix &C)//相加{if(A.m==B.m&&A.n==B.n){int i=0,j=0;int k=0;C.m=A.m;C.n=A.n;while( i<A.len||j<B.len){if(i==A.len&&j<B.len){C.date[k].col=B.date[j].col;C.date[k].row=B.date[j].row;C.date[k++].e=B.date[j].e;C.len++;j++;}else if(i<A.len&&j==B.len)C.date[k].col=A.date[i].col;C.date[k].row=A.date[i].row;C.date[k++].e=A.date[i].e;C.len++;i++;}else{if(A.date[i].row>B.date[j].row){C.date[k].col=B.date[j].col;C.date[k].row=B.date[j].row;C.date[k++].e=B.date[j].e;C.len++;j++;}else if(A.date[i].row<B.date[j].row){C.date[k].col=A.date[i].col;C.date[k].row=A.date[i].row;C.date[k++].e=A.date[i].e;C.len++;i++;}else{if(A.date[i].col==B.date[j].col){if(A.date[i].e+B.date[j].e!=0){C.date[k].col=A.date[i].col;C.date[k].row=A.date[i].row;C.date[k++].e=A.date[i].e+B.date[j].e;C.len++;}i++;j++;}else if(A.date[i].col>B.date[j].col){C.date[k].col=B.date[j].col;C.date[k].row=B.date[j].row;C.date[k++].e=B.date[j].e;C.len++;j++;}else if(A.date[i].col<B.date[j].col){C.date[k].col=A.date[i].col;C.date[k].row=A.date[i].row;C.date[k++].e=A.date[i].e;C.len++;i++;}}}}}else{cout<<"不能相加!";}}void sub(TSMatrix A,TSMatrix &B,TSMatrix &C)//相减{for(int k=0;k<B.len;k++){B.date[k].e=-B.date[k].e;}if(A.m==B.m&&A.n==B.n){add(A,B,C);}elsecout<<"不能相减!";for( k=0;k<B.len;k++){B.date[k].e=-B.date[k].e;}}int search(TSMatrix A,int m,int n){int flag=-1;for(int i=0;i<MAXSIZE;i++){if(A.date[i].row==m&&A.date[i].col==n){flag=i;break;}}return flag;}void mult(TSMatrix A,TSMatrix B,TSMatrix &C)//相乘{int i=0,j=0;if(A.n==B.m){C.m=A.m;C.n=B.n;for(i=0;i<A.len;i++){for(j=0;j<B.len;j++){if(A.date[i].col==B.date[j].row){int flag=search(C,A.date[i].row,B.date[j].col);if(flag==-1){C.date[C.len].col=B.date[j].col;C.date[C.len].row=A.date[i].row;C.date[C.len++].e=A.date[i].e*B.date[j].e;}else{C.date[flag].e=C.date[flag].e+A.date[i].e*B.date[j].e;}}}}}else{cout<<"不能相乘!"<<endl;}}void print(TSMatrix A){int k=0;int i,j;int M[MAXSIZE][MAXSIZE];for(i=0;i<A.m;i++){for(j=0;j<A.n;j++){M[i][j]=0;}}while(k<A.len){M[A.date[k].row-1][A.date[k].col-1]=A.date[k].e;k++;}for(i=0;i<A.m;i++){cout<<"| ";for(j=0;j<A.n;j++){cout<<M[i][j]<<" ";}cout<<"|"<<endl;}}void showtip(){cout<<"------------请选择要执行的操作--------"<<endl;cout<<endl;cout<<" 0---创建矩阵"<<endl;cout<<" 1---A+B"<<endl;cout<<" 2---A-B"<<endl;cout<<" 3---A*B"<<endl;cout<<" 4---退出"<<endl;cout<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;}3、主函数:void main(){TSMatrix A,B,C;initMatrix(A);initMatrix(B);initMatrix(C);showtip();int i;cin>>i;while(true){switch(i){case 0:system("cls");cout<<"创建矩阵A:"<<endl;createMatrix(A);cout<<"创建矩阵B:"<<endl;createMatrix(B);showtip();break;case 1:system("cls");if(A.m==0||B.m==0){cout<<"未建矩阵"<<endl;}else{initMatrix(C);add(A,B,C);if(A.m==B.m&&A.n==B.n){cout<<"加的结果;"<<endl;print(A);cout<<"+"<<endl;;print(B);cout<<"="<<endl;print(C);}}break;case 2:system("cls");if(A.m==0||B.m==0){cout<<"未建矩阵"<<endl;}else{initMatrix(C);sub(A,B,C);cout<<"减的结果;"<<endl;print(A);cout<<"+"<<endl;;print(B);cout<<"="<<endl;print(C);}showtip();break;case 3:system("cls");if(A.m==0||B.m==0){cout<<"未建矩阵"<<endl;}else{initMatrix(C);mult(A,B,C);if(A.n==B.m){cout<<"乘后的结果;"<<endl;print(A);cout<<"*"<<endl;print(B);cout<<"="<<endl;print(C);}}showtip();break;case 4:break;}cin>>i;}}四、调试分析1、由于本程序涉及的函数比较多,所以开始时在函数调用上出现了混乱,把自己都给搞糊涂了,后来经仔细排查,最终发现了错误。
稀疏矩阵数据结构实验报告
目录1.需求分析 (1)2.概要设计 (2)2.1链表对稀疏矩阵进行定义 (2)2.3程序一共有五个功能 (2)3.详细设计 (3)3.1稀疏矩阵存储算法分析 (3)3.2稀疏矩阵各运算算法分析 (3)4.调试分析 (8)4.1调试过程中的问题及解决方法 (8)4.2算法的时间复杂度和空间复杂 (8)4.3经验和体会 (8)5.用户使用说明 (9)6.测试结果 (10)6.1程序主界面 (10)6.2其他函数操作界面显示 (10)参考文献 (15)致谢 (16)1.需求分析矩阵在日常生活中应用广泛,尤其是有些特殊矩阵的运算。
但是在实际应用中有一种矩阵,在m×n的矩阵中有t个非零元素,且t远小于m×n,我们这样的矩阵被称为稀疏矩阵。
由于这类矩阵中通常零元素是没有规律的,为了能够找到相应的元素,仅存储非零元素的值是不行的,还要存储其所在的行和列等信息。
本程序主要的任务是创建稀疏矩阵,并且利用C++算法程序实现相应的运算(转置,加法,减法,乘法)(1)输入的形式以及范围:键盘输入符合要求的稀疏矩阵。
(2)输出形式:最终运算结果以矩阵的形式输出。
(3)程序功能实现:输入矩阵通过程序运算出相应的转置矩阵以及两个符合要求的矩阵的加减乘除法的运算。
(4)测试数据:如果输入正确,程序会显示最后的运算结果;否则错误时则会返回上层。
2.概要设计要存储稀疏矩阵并且进行运算,那么就要了解稀疏矩阵的存储结构,这里采用链表的形式存储稀疏矩阵并进行运算。
2.1链表对稀疏矩阵进行定义typedef struct OLNode{ // 定义链表元素int i,j;int e;struct OLNode *next; // 该非零元所在行表和列表的后继元素}OLNode,*OLink;typedef struct{ // 定义链表对象结构体OLink *head; //头指针int mu,nu,tu; // 行数,列数,和非零元素个数}CrossList;2.3程序一共有五个功能1.用CreateSMatrix_OL(M)函数来实现稀疏矩阵的存储,用OutPutSMatrix_OL(M)函数实现稀疏矩阵的输出。
数据结构实验报告稀疏矩阵运算
数据结构实验报告稀疏矩阵运算实验目的:1.学习并理解稀疏矩阵的概念、特点以及存储方式。
2.掌握稀疏矩阵加法、乘法运算的基本思想和算法。
3.实现稀疏矩阵加法、乘法的算法,并进行性能测试和分析。
实验原理:稀疏矩阵是指矩阵中绝大多数元素为0的矩阵。
在实际问题中,有许多矩阵具有稀疏性,例如文本矩阵、图像矩阵等。
由于存储稀疏矩阵时,对于大量的零元素进行存储是一种浪费空间的行为,因此需要采用一种特殊的存储方式。
常见的稀疏矩阵的存储方式有三元组顺序表、十字链表、行逻辑链接表等。
其中,三元组顺序表是最简单直观的一种方式,它是将非零元素按行优先的顺序存储起来,每个元素由三个参数组成:行号、列号和元素值。
此外,还需要记录稀疏矩阵的行数、列数和非零元素个数。
稀疏矩阵加法的原理是将两个稀疏矩阵按照相同的行、列顺序进行遍历,对于相同位置的元素进行相加,得到结果矩阵。
稀疏矩阵乘法的原理是将两个稀疏矩阵按照乘法的定义进行计算,即行乘以列的和。
实验步骤:1.实现稀疏矩阵的三元组顺序表存储方式,并完成稀疏矩阵的初始化、转置、打印等基本操作。
2.实现稀疏矩阵的加法运算,并进行性能测试和分析。
3.实现稀疏矩阵的乘法运算,并进行性能测试和分析。
4.编写实验报告。
实验结果:经过实验测试,稀疏矩阵的加法和乘法算法都能正确运行,并且在处理稀疏矩阵时能够有效节省存储空间。
性能测试结果表明,稀疏矩阵加法、乘法的运行时间与非零元素个数有关,当非零元素个数较少时,运算速度较快;当非零元素个数较多时,运算速度较慢。
实验分析:稀疏矩阵的运算相对于普通矩阵的运算有明显的优势,可以节省存储空间和运算时间。
在实际应用中,稀疏矩阵的存储方式和运算算法都可以进行优化。
例如,可以采用行逻辑链接表的方式存储稀疏矩阵,进一步减少存储空间的占用;可以采用并行计算的策略加快稀疏矩阵的运算速度。
总结:通过本次实验,我深入学习了稀疏矩阵的概念、特点和存储方式,掌握了稀疏矩阵加法、乘法的基本思想和算法,并通过实验实现了稀疏矩阵的加法、乘法运算。
实验五 稀疏矩阵的实验
实验五稀疏矩阵的实验【实验目的】1、掌握稀疏矩阵的三元组表示法2、学会应用稀疏矩阵的三元组表示法实现稀疏矩阵的运算【实验说明】参考下列步骤完成实验1、三元组存储结构定义# include <stdio.h># include <stdlib.h># define MAXSIZE 1000typedef int ElementType;typedef struct{int row,col;ElementType e;}Triple;typedef struct{Triple data[MAXSIZE+1];int m,n,len;}TSMatrix;2、创建三元组void CreateTmatrix (TSMatrix *A){int i,j; ElementType x;int p;printf("请输入矩阵总的行数,列数及非零元的个数(逗号相隔):");scanf("%d,%d,%d",&A->m,&A->n,&A->len);printf("\n请输入矩阵的三元组(逗号相隔)\n");for(p=1;p<=A->len;p++){scanf("%d,%d,%d",&i,&j,&x);A->data[p].row=i;A->data[p].col=j;A->data[p].e=x;}}//CreateTmatrix3、应用三元组存储稀疏矩阵并实现由矩阵A得其转置矩阵Bvoid TransposeTSMatrix(TSMatrix A,TSMatrix *B){//把矩阵A转置到B所反指向的矩阵中去。
矩阵用三元组表示int i,j,k;B->m=A.n;B->n=A.m;B->len=A.len;if(B->len>0){j=1;for(k=1;k<=A.n;k++)for(i=1;i<=A.len;i++)if(A.data[i].col==k){B->data[j].row=A.data[i].col;B->data[j].col=A.data[i].row;B->data[j].e=A.data[i].e;j++;}}}//TransposeTSMatrix4、以矩阵形式输出稀疏矩阵void output1(TSMatrix A){ ElementType M[50][50];int i,j,rmax,cmax;rmax=A.m; //得到最大的行数cmax=A.n;for(i=0;i<rmax;i++)for(j=0;j<cmax;j++)M[i][j]=0;for(i=1;i<=A.len;i++)M[A.data[i].row-1][A.data[i].col-1]=A.data[i].e;for(i=0;i<rmax;i++){ for(j=0;j<cmax;j++) printf("%5d ",M[i][j]);printf("\n");}}5、以三元组形式输出稀疏矩阵void output3(TSMatrix A) {int i;printf("\n");for(i=1;i<=A.len;i++){ printf(" %3d %3d %3d",A.data[i].row,A.data[i].col,A.data[i].e);printf("\n");}}//output3//主调函数void main(){TSMatrix A,B;CreateTmatrix(&A);printf("原矩阵:\n");output1(A);TransposeTSMatrix(A,&B);printf("\n转置矩阵:\n");output1(B);printf("\n转置矩阵的三元组形式:\n");output3(B);}【实验内容】⑴以一次定位快速转置法实现稀疏矩阵的转置运算;⑵若矩阵A m×n中的某个元素a ij是第i行中的最小值,同时又是第j 列中的最大值,则称此元素为该矩阵中的一个马鞍点。
数据结构实验报告稀疏矩阵运算
教学单位计算机科学与技术学生学号************数据结构课程设计报告书题目稀疏矩阵运算器学生姓名秦豹专业名称软件工程指导教师李志敏实验目的:深入研究数组的存储表示和实现技术,熟悉广义表存储结构的特性。
需要分析:稀疏矩阵是指那些多数元素为零的矩阵。
利用“稀疏”特点进行存储和计算可以大大节省存储空间,提高计算效率。
实现一个能进行稀疏矩阵基本运算的运算器。
要求以带“行逻辑链接信息”的三元组顺序表存储稀疏矩阵,实现两矩阵的相加、相减、相乘等运算。
输入以三元组表示,输出以通常的阵列形式列出。
软件平台:Windows 2000,Visual C++6.0或WINTC概要设计:ADT Array {数据对象:D = {aij | 0≤i≤b1-1, 0 ≤j≤b2-1}数据关系:R = { ROW, COL }ROW = {<ai,j,ai+1,j>| 0≤i≤b1-2, 0≤j≤b2-1}COL = {<ai,j,ai,j+1>| 0≤i≤b1-1, 0≤j≤b2-2}基本操作:CreateSMatrix(&M); //操作结果:创建稀疏矩阵M.Print SMatrix(M);//初始化条件: 稀疏矩阵M存在.//操作结果:输出稀疏矩阵M.AddSMatrix(M,N,&Q);//初始化条件: 稀疏矩阵M与N的行数和列数对应相等.//操作结果:求稀疏矩阵的和Q=M+N.SubSMatrix(M,N,&Q);//初始化条件: 稀疏矩阵M与N的行数和列数对应相等.//操作结果:求稀疏矩阵的差Q=M-N.MultSMatrix(M,N,&Q);//初始化条件: 稀疏矩阵M的列数等于N的行数.//操作结果:求稀疏矩阵的乘积Q=M*N.} ADT Array调试测试:初始界面矩阵的加法矩阵的减法矩阵的转置矩阵的乘法程序源码:#include<stdio.h>#include<malloc.h>#include<stdlib.h>#define MAXSIZE 40 //假设非零元素个数的最大值为40#define MAXRC 20 //假设矩阵的最大行数为20typedef int ElemType;typedef struct{int i,j; //非零元的行下标和列下标ElemType e; //非零元的值}Triple;typedef struct{Triple data[MAXSIZE+1];int rpos[MAXRC+1]; //各行第一个非零元在三元组的位置表int hs,ls,fls;}TSMatrix,*Matrix;void Creat(TSMatrix &M){int i,k;for(i=1;i<=MAXRC+1;i++)M.rpos[i]=0;printf("请输入矩阵的行数、列数和非零元个数(以空格隔开):");scanf("%d %d %d",&M.hs,&M.ls,&M.fls);for(i=1;i<=M.fls;i++){printf("请用三元组形式输入矩阵的元素(行列非零元素):");scanf("%d %d %d",&M.data[i].i,&M.data[i].j,&M.data[i].e);}for(i=1,k=1;i<=M.hs;i++){M.rpos[i]=k;while(M.data[k].i<=i && k<=M.fls)k++;}}void Xiangjia(TSMatrix A,TSMatrix B,TSMatrix &C,int n){int a,b,temp,l;C.hs=A.hs;C.ls=A.ls;a=b=l=1;while(a<=A.fls && b<=B.fls){if(A.data[a].i==B.data[b].i){if(A.data[a].j<B.data[b].j)C.data[l++]=A.data[a++];else if(A.data[a].j>B.data[b].j){C.data[l]=B.data[b]; C.data[l++].e=n*B.data[b++].e;}else{temp=A.data[a].e+n*B.data[b].e;if(temp){C.data[l]=A.data[a];C.data[l].e=temp;l++;}a++;b++;}}else if(A.data[a].i<B.data[b].i)C.data[l++]=A.data[a++];else {C.data[l]=B.data[b]; C.data[l++].e=n*B.data[b++].e;} }while(a<=A.fls)C.data[l++]=A.data[a++];while(b<=B.fls){C.data[l]=B.data[b]; C.data[l++].e=n*B.data[b++].e;}C.fls=l-1;}int Xiangcheng(TSMatrix A,TSMatrix B,TSMatrix &Q){int arow,brow,ccol,tp,p,q,t;int ctemp[MAXRC+1];if(A.ls!=B.hs) return 0;Q.hs=A.hs;Q.ls=B.ls;Q.fls=0;if(A.fls*B.fls){for(arow=1;arow<=A.hs;arow++){for(ccol=1;ccol<=Q.ls;ccol++)ctemp[ccol]=0;Q.rpos[arow]=Q.fls+1;if(arow<A.hs) tp=A.rpos[arow+1];else tp=A.fls+1;for(p=A.rpos[arow];p<tp;p++){brow=A.data[p].j;if(brow<B.hs) t=B.rpos[brow+1];else t=B.fls+1;for(q=B.rpos[brow];q<t;q++){ccol=B.data[q].j;ctemp[ccol]+=A.data[p].e*B.data[q].e;}}for(ccol=1;ccol<=Q.ls;ccol++){if(ctemp[ccol]){if(++Q.fls>MAXSIZE) return 0;Q.data[Q.fls].i=arow;Q.data[Q.fls].j=ccol;Q.data[Q.fls].e=ctemp[ccol];}}}}return 1;}void Print_SMatrix(TSMatrix M){int k,l,n;Matrix p;p=&M;for(k=1,n=1;k<=p->hs;k++){for(l=1;l<=p->ls;l++){if(p->data[n].i==k && p->data[n].j==l){printf("%5d",p->data[n].e);n++;}elseprintf("%5d",0);}printf("\n");}printf("\n");}void Zhuanzhi(TSMatrix *a,TSMatrix *b){int q,col,p;b->hs=a->ls;b->ls=a->hs;b->fls=a->fls;if(b->fls){q=1;for(col=1;col<=a->ls;col++)for(p=1;p<=a->fls;p++)if(a->data[p].j==col){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;}}}void Destory_SMatrix(TSMatrix &M){M.hs=M.ls=M.fls=0;}void main(){TSMatrix A,B,C;TSMatrix *p=&A,*q=&B;int flag,n;while(1){system("cls");printf("\n\n\n");printf("\t┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");printf("\t┃*** 稀疏矩阵的加、减、转、乘*** ┃\n");printf("\t┣━━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n");printf("\t┃1、稀疏矩阵的加法┃\n");printf("\t┃2、稀疏矩阵的减法┃\n");printf("\t┃3、稀疏矩阵的转置┃\n");printf("\t┃4、稀疏矩阵的乘法┃\n");printf("\t┃5、退出该应用程序┃\n");printf("\t┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");printf("输入要进行的项目的编号:");scanf("%d",&flag);if(flag==5) break;Creat(A);printf("矩阵A:\n"); Print_SMatrix(A);switch(flag){case 1: Creat(B);n=1;printf("矩阵B:\n");Print_SMatrix(B);if(A.hs==B.hs && A.ls==B.ls){printf("A+B:\n");Xiangjia(A,B,C,n);Print_SMatrix(C);}else printf("错误!行列不一致\n");break;case 2: Creat(B);n=-1;printf("矩阵B:\n");Print_SMatrix(B);if(A.hs==B.hs && A.ls==B.ls){printf("A-B:\n");Xiangjia(A,B,C,n);Print_SMatrix(C);}else printf("错误!行列不一致\n");break;case 3: printf("A->B:\n");Zhuanzhi(p,q);Print_SMatrix(B);break;case 4: Creat(B);printf("矩阵B:\n");Print_SMatrix(B);printf("A*B:\n");n=Xiangcheng(A,B,C);if(!n) printf("错误!行列不匹配\n");else Print_SMatrix(C);break;default: printf("输入错误!\n");}Destory_SMatrix(A);Destory_SMatrix(B);Destory_SMatrix(C);getchar();getchar();}printf("\n\t\t\t ***程序已经退出***\n");getchar();}小结:。
稀疏矩阵实验报告(包括问题描述,源代码,实验结果等)
数据结构课程设计实习报告题目:班级:学号:姓名:实习报告1.问题描述稀疏矩阵的操作基本功能要求:(1)稀疏矩阵采用三元组表示,求两个具有相同行列数的稀疏矩阵A和B的相加矩阵C,并输出C。
(2)求出A的转置矩阵D,输出D。
2.设计1)设计思想矩阵中如果多数的元素没有数据,则会造成存储器空间的浪费,为此,必须设计稀疏矩阵的阵列储存方式,利用较少的存储器空间储存完整的矩阵数据。
但是这些存储空间的大部分存放的是0元素,从而造成大量的空间浪费.为了节省存储空间,可以只存储其中的非0元素. 对于矩阵Amn的每个元素aij,知道其行号i 和列号j就可以确定其位置.因此对于稀疏矩阵可以用一个结点来存储一个非0元素.该结点可以定义成: [i,j,aij]创建一个矩阵A和矩阵B,这两个稀疏矩阵具有相同行列数,然后矩阵A与矩阵B相加得到矩阵C,并输出C,稀疏矩阵采用三元组表示。
并调用原矩阵A 转置得到矩阵D,输出D。
2) 设计表示法(1) 函数调用关系如图所示。
3)实现注释:实现了原题中要求的:两个具有相同行列数的稀疏矩阵A和B的相加矩阵C,并输出C;得到矩阵A的转置矩阵D,输出D;稀疏矩阵均采用三元组表示。
3.调试报告调试程序时,应注意矩阵的调用。
比如,开始的时候没有注意将程序调用,最后尽管实现了矩阵的转置和相加,但没有符合题意。
题目要求的是用创建好的矩阵A和矩阵B进行相加,并对矩阵A进行转置,所以要调用好矩阵。
4.程序清单#include<stdio.h>#include<stdlib.h>#define MAXSIZE 100typedef struct{int i,j;int e;}Triple;typedef struct{Triple data[MAXSIZE+1];int mu,nu,tu; //mu、nu为稀疏矩阵的行列数,tu为稀疏矩阵的非零元素个数}TSMatrix;TSMatrix M,T,S,B,C;void CreateMatrix(TSMatrix &M){int i,elem,col,row,mu,nu,tu;printf("请输入稀疏矩阵的行数、列数和非零元素的个数:\n");scanf("%d%d%d",&mu,&nu,&tu);M.mu=mu;M.nu=nu;M.tu=tu;for (i=1;i<=tu;i++){printf("请输入非零元素的行号、列号和值:\n");scanf("%d%d%d",&col,&row,&elem);if ( mu<=1 || col>M.mu ||nu<=1 || row>M.nu){printf("error!");exit(0);}else{M.data[i].i=col; //输出这个三元组M.data[i].j=row;M.data[i].e=elem;}}}void FastTransposeSMatrix(TSMatrix M) /*求转置矩阵*/ {int num[100];int cpot[100];int p,q,t,col=0;T.mu=M.nu; // 给T的行、列数与非零元素个数赋值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]++;}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]++;}} TSMatrix(T);}void TSMatrix_add(TSMatrix M,TSMatrix T,TSMatrix &ADD) /*求矩阵的和*/ {int a=1,b=1,c=1,x;ADD.mu=M.mu;ADD.nu=M.nu;ADD.tu=0;for(x=1;x<=M.mu;x++){while(M.data[a].i==x&&T.data[b].i==x){if(M.data[a].j==T.data[b].j){ADD.data[c].i=M.data[a].i;ADD.data[c].j=M.data[a].j;ADD.data[c].e=M.data[a].e+T.data[b].e;c++;a++;b++;}else if(M.data[a].j<T.data[b].j){ADD.data[c].i=M.data[a].i;ADD.data[c].j=M.data[a].j;ADD.data[c].e=M.data[a].e;c++;a++;}else{ADD.data[c].i=T.data[b].i;ADD.data[c].j=T.data[b].j;ADD.data[c].e=T.data[b].e;c++;b++;}}while(M.data[a].i==x){ADD.data[c].i=M.data[a].i;ADD.data[c].j=M.data[a].j;ADD.data[c].e=M.data[a].e;c++;a++;while(T.data[b].i==x){ADD.data[c].i=T.data[b].i;ADD.data[c].j=T.data[b].j;ADD.data[c].e=T.data[b].e;c++;b++;}}ADD.tu=c-1;}void ShowMatrix(TSMatrix &M) /*打印出矩阵*/ {int i=1,j=1,dir=1;//printf("稀疏矩阵为:\n");for(i=1;i<=M.mu;i++){for(j=1;j<=M.nu;j++){if(M.data[dir].i==i && M.data[dir].j==j) {printf("%d ",M.data[dir].e);dir++;}elseprintf("0 ");}printf("\n");}void main(){while(1){int c;M.mu=0;M.nu=0;M.tu=0;printf("1.创建一个稀疏矩阵A:\n");printf("2.求转置矩阵A:\n");printf("3.创建一个稀疏矩阵B:\n");printf("4.求转置矩阵B:\n");printf("5.求A与B原矩阵的和:\n"); while (1){printf("请按键选择:");scanf("%d",&c);switch(c){case 1:CreateMatrix(M) ;break;case 2:FastTransposeSMatrix(M);printf("原矩阵A为:\n");ShowMatrix(M);printf("转置矩阵为:\n"); ShowMatrix(T);break;case 3:CreateMatrix(B) ;break;case 4:FastTransposeSMatrix(B);printf("原矩阵B为:\n");ShowMatrix(B);printf("转置矩阵为:\n");ShowMatrix(T);break;case 5:FastTransposeSMatrix(M);TSMatrix_add(M,B,S);printf("A与B原矩阵的和为:\n");ShowMatrix(S);break;return 0;}}}}5.结果分析(1)选择选项1,创建矩阵A;选择选项2,转置矩阵A。
实现稀疏矩阵的基本运算实验报告
实现稀疏矩阵的基本运算实验报告实验报告:稀疏矩阵的基本运算实验一、引言稀疏矩阵是指在矩阵中大部分元素为0的情况下,只存储非零元素及其位置信息的数据结构。
由于稀疏矩阵节省空间,可以节约存储和计算时间,因此在科学计算和大规模矩阵运算中应用广泛。
本实验旨在实现稀疏矩阵的基本运算,包括矩阵加法、矩阵乘法和转置运算,并对其效率进行测试。
二、实验方法本实验使用C++语言实现稀疏矩阵的基本运算。
首先定义一个稀疏矩阵的结构体,包括矩阵的行数、列数、非零元素个数和一个动态分配的二维数组用于存储非零元素的值和位置信息。
然后根据实验要求,分别实现矩阵的加法、乘法和转置运算的函数。
1.矩阵加法:遍历两个矩阵的非零元素,将对应位置的元素相加存入结果矩阵。
2.矩阵乘法:遍历两个矩阵的非零元素,将对应位置的元素相乘并累加,存入结果矩阵。
3.转置运算:将矩阵的行列互换,同时调整非零元素的位置信息。
最后,通过随机生成不同大小的稀疏矩阵进行实验,并记录每种运算的运行时间,分析稀疏矩阵在不同运算中的效率差异。
三、实验结果1.矩阵加法运算:对两个1000*1000的稀疏矩阵进行加法运算,耗时0.05秒。
2.矩阵乘法运算:对一个1000*1000和一个1000*100的稀疏矩阵进行乘法运算,耗时0.1秒。
四、实验结论通过实验结果可以看出,稀疏矩阵的加法运算具有较高的效率,因为只需要遍历非零元素进行相加,而对于乘法运算和转置运算,由于需要遍历较多的元素进行累加或位置调整,因此耗时较长。
在矩阵转置运算中,由于矩阵规模较大,耗时最长。
总结而言,稀疏矩阵在处理大规模矩阵运算时具有一定的优势,可以节约存储空间和计算时间。
在实践中,可以根据应用的需求选择适当的数据结构和算法,进一步提升稀疏矩阵的运算效率。
五、实验反思本实验中,由于时间和资源限制,只对较小规模的稀疏矩阵进行了测试,实际应用中可能会遇到更大规模的矩阵运算问题,因此需要进一步验证和优化。
数据结构-稀疏矩阵-实验报告与代码
一.需求分析输入要求:稀疏矩阵的行、列和非零元素个数输出要求:稀疏矩阵的转置、加法、减法、乘法二.算法设计本程序中采用的数据模型,用到的抽象数据类型的定义,程序的主要算法流程及各模块之间的层次调用关系1.抽象数据类型:ADT List {数据对象:D={ai:|ai∈ElemSet,i=1…n,n≥0}数据关系:R={Row,Col}Row={<ai,j,ai,j>|1<=i<=m,1<=j<=n-1}Col={<ai,j,ai,j>|1<=i<=m-1,1<=j<=n}基本操作:Status CreateSMatrix(TSMatrix &M)操作结果:初始化稀疏数组void PrintSMatrix(TSMatrix M)初始条件:稀疏数组M已经存在操作结果:打印矩阵Mvoid DestroySMatrix(TSMatrix &M)初始条件:稀疏数组M已经存在操作结果:销毁矩阵Mvoid CopySMatrix(TSMatrix M, TSMatrix &T)初始条件:稀疏数组M已经存在操作结果:复制矩阵M到TStatus AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)初始条件:稀疏数组M、N已经存在操作结果:求矩阵的和Q=M+NStatus SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)初始条件:稀疏数组M、N已经存在操作结果:求矩阵的差Q=M-NStatus TransposeSMatrix(TSMatrix M, TSMatrix & T)初始条件:稀疏数组M已经存在操作结果:求矩阵M的转置TStatus MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)初始条件:稀疏数组M已经存在操作结果:求矩阵的积Q=M*N}ADT List2. 本程序有二个模块:(1)主程序模块main(){初始化;{接受命令;显示结果;}}(2)三元组表单元模块:实现矩阵抽象数据类型。
稀疏矩阵实验报告
一、实验目的1. 理解稀疏矩阵的概念和特点。
2. 掌握稀疏矩阵的三元组表示方法。
3. 熟悉稀疏矩阵的基本运算,如转置、加法、减法等。
4. 提高编程能力和问题解决能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 2019三、实验内容1. 稀疏矩阵的三元组表示- 设计稀疏矩阵的三元组存储结构。
- 编写函数实现稀疏矩阵的三元组表示。
2. 稀疏矩阵的基本运算- 实现稀疏矩阵的转置。
- 实现稀疏矩阵的加法、减法。
- 实现稀疏矩阵的乘法。
3. 实验结果分析- 对实验结果进行分析,比较稀疏矩阵与普通矩阵运算的效率。
四、实验步骤1. 稀疏矩阵的三元组表示- 定义稀疏矩阵的三元组存储结构,包括行号、列号和元素值。
- 编写函数实现稀疏矩阵的三元组表示,包括读取稀疏矩阵的三元组数据、构建稀疏矩阵的三元组表示等。
2. 稀疏矩阵的基本运算- 实现稀疏矩阵的转置,包括交换行号和列号、重新排序等。
- 实现稀疏矩阵的加法、减法,包括遍历两个稀疏矩阵的三元组,计算对应元素的加法或减法结果。
- 实现稀疏矩阵的乘法,包括遍历两个稀疏矩阵的三元组,计算对应元素的乘法结果。
3. 实验结果分析- 对实验结果进行分析,比较稀疏矩阵与普通矩阵运算的效率。
- 分析实验结果,得出稀疏矩阵运算的优缺点。
五、实验结果1. 稀疏矩阵的三元组表示- 读取稀疏矩阵的三元组数据,构建稀疏矩阵的三元组表示。
2. 稀疏矩阵的基本运算- 实现稀疏矩阵的转置,包括交换行号和列号、重新排序等。
- 实现稀疏矩阵的加法、减法,包括遍历两个稀疏矩阵的三元组,计算对应元素的加法或减法结果。
- 实现稀疏矩阵的乘法,包括遍历两个稀疏矩阵的三元组,计算对应元素的乘法结果。
3. 实验结果分析- 稀疏矩阵运算效率比普通矩阵运算高,尤其在稀疏程度较高的矩阵上。
- 稀疏矩阵运算的缺点是存储空间较大,且运算过程中需要频繁进行数据交换。
数据结构稀疏矩阵应用
实验五数组的运算实验目的:掌握稀疏矩阵的压缩存储方法及主要运算的实现。
实验内容与要求:设计一个稀疏矩阵计算器,要求能够:⑴输入并建立稀疏矩阵;⑵输出稀疏矩阵;⑶执行两个矩阵相加;⑷求一个矩阵的转置矩阵。
程序代码:#include<stdio.h>#define smax 20typedef int datatype;typedef struct{ int i,j;datatype v;}node;typedef struct{ node data[smax];int m,n,t;}spmatrix;void creat(spmatrix a)\\创建输出稀疏矩阵{ int k=0;printf("请输入稀疏矩阵:\n");scanf("%d,%d,%d",&a.m,&a.n,&a.t);scanf("%d,%d,%d",&a.data[0].i,&a.data[0].j,&a.data[0].v);while(a.data[k].v!=0)\\以0元素作为结束标志,因为稀疏矩阵不包含0元素{k++;scanf("%d,%d,%d",&a.data[k].i,&a.data[k].j,&a.data[k].v);}printf("输出的稀疏矩阵是:\n");printf("%d,%d,%d\n",a.m,a.n,a.t);for(k=0;k<a.t;k++)\\一维数组思想,用for循环简单printf("%d,%d,%d\n",a.data[k].i,a.data[k].j,a.data[k].v);printf("\n");}void transpose(spmatrix a)\\转置函数{ int p,q,k=0;printf("请输入稀疏矩阵:\n");scanf("%d,%d,%d",&a.m,&a.n,&a.t);scanf("%d,%d,%d",&a.data[0].i,&a.data[0].j,&a.data[0].v);while(a.data[k].v!=0){k++;scanf("%d,%d,%d",&a.data[k].i,&a.data[k].j,&a.data[k].v);}for(k=0;k<a.t;k++)\\行列交换即可,但没有进行排序输出{p=a.data[k].i;a.data[k].i=a.data[k].j;a.data[k].j=p;}printf("输出转置后的初步矩阵元素:\n");for(k=0;k<a.t;k++)printf("%d,%d,%d\n",a.data[k].i,a.data[k].j,a.data[k].v);for(p=0;p<a.t;p++)\\冒泡排序法,对转置后的稀疏矩阵进行重新排序for(k=0;k<(a.t-p);k++){if(a.data[k].i>a.data[k+1].i || (a.data[k].i==a.data[k+1].i &&a.data[k].j>a.data[k+1].j)){q=a.data[k].i;a.data[k].i=a.data[k+1].i;a.data[k+1].i=q;q=a.data[k].j;a.data[k].j=a.data[k+1].j;a.data[k+1].j=q;q=a.data[k].v;a.data[k].v=a.data[k+1].v;a.data[k+1].v=q;}}printf("输出转置后的稀疏矩阵:\n");printf("%d,%d,%d\n",a.n,a.m,a.t);for(k=1;k<(a.t+1);k++)\\此处下标加1是根据输出结果判定而来,不知道原因printf("%d,%d,%d\n",a.data[k].i,a.data[k].j,a.data[k].v);printf("\n");}void add(spmatrix a,spmatrix b)\\求和函数{spmatrix c;int x=0,y=0,z=0;int p,q,r=0;printf("请输入稀疏矩阵a:\n");scanf("%d,%d,%d",&a.m,&a.n,&a.t);scanf("%d,%d,%d",&a.data[0].i,&a.data[0].j,&a.data[0].v);while(a.data[x].v!=0){x++;scanf("%d,%d,%d",&a.data[x].i,&a.data[x].j,&a.data[x].v);}printf("请输入稀疏矩阵b:\n");scanf("%d,%d,%d",&b.m,&b.n,&b.t);scanf("%d,%d,%d",&b.data[0].i,&b.data[0].j,&b.data[0].v);while(a.data[y].v!=0){y++;scanf("%d,%d,%d",&b.data[y].i,&b.data[y].j,&b.data[y].v);}\\以上为重新创建两个稀疏矩阵,方便运算if(a.m==b.m && a.n==b.n)\\首先行列相等的稀疏矩阵才能相加{for(x=0;x<a.t;x++){c.data[z].i=a.data[x].i;c.data[z].j=a.data[x].j;c.data[z].v=a.data[x].v;z++;}for(y=0;y<a.t;y++){c.data[z].i=b.data[y].i;c.data[z].j=b.data[y].j;c.data[z].v=b.data[y].v;z++;}\\两个for循环先后把a,b两个稀疏矩阵元素放到一个新的稀疏矩阵c里去printf("输出结合后的初步稀疏矩阵C的元素:\n");\\进行一次打印for(z=0;z<(a.t+b.t);z++)printf("%d,%d,%d\n",c.data[z].i,c.data[z].j,c.data[z].v);for(p=0;p<(a.t+b.t);p++)\\冒泡排序法对新矩阵元素排序for(z=0;z<(a.t+b.t-p);z++){if(c.data[z].i>c.data[z+1].i || (c.data[z].i==c.data[z+1].i &&c.data[z].j>c.data[z+1].j))\\有这几种情况需要重新排序,首先是进行行对比(前行大于后行进行交换),然后当行相等时在进行列对比(前列大于后列时在进行交换),其他情况均不用交换{q=c.data[z].i;c.data[z].i=c.data[z+1].i;c.data[z+1].i=q;q=c.data[z].j;c.data[z].j=c.data[z+1].j;c.data[z+1].j=q;q=c.data[z].v;c.data[z].v=c.data[z+1].v;c.data[z+1].v=q;}}printf("输出排序后的稀疏矩阵C的元素:\n");\\进行一次打印for(z=1;z<(a.t+b.t+1);z++)printf("%d,%d,%d\n",c.data[z].i,c.data[z].j,c.data[z].v);for(z=1;z<(a.t+b.t+1-r);z++)\\主循环,保证阅读每一个数组元素if(c.data[z].i==c.data[z+1].i && c.data[z].j==c.data[z+1].j) \\在对排好序后的矩阵进行相等行列元素的合并{c.data[z].v=c.data[z].v+c.data[z+1].v;r++;\\此处是关键,记录此时的步骤,如果进行一次运算后,那么后面的循环就要少一次,包括再回到主循环时也要少一次for(z+1;(z+1)<(a.t+b.t+1-r);z++)\\小循环是让后面的每一个数组元素向前移动一个位置,掩盖掉相等行列元素{c.data[z+1].i=c.data[z+2].i;c.data[z+1].j=c.data[z+2].j;c.data[z+1].v=c.data[z+2].j;}}printf("输出最终结果的稀疏矩阵C:\n");printf("%d,%d,%d\n",a.m,a.n,(a.t+b.t-r));\\输出稀疏矩阵表头时只需将行列元素交换输出即可,元素个数输出时要注意相等行列元素合并进行了几次操作,即用r记录操作步骤的次数,每进行一次操作那么最终稀疏矩阵就少一个数组元素,同时r又是伴随步骤增加的for(z=1;z<(a.t+b.t+1-r);z++)\\原理同上printf("%d,%d,%d\n",c.data[z].i,c.data[z].j,c.data[z].v);}Else\\给出稀疏矩阵表开头行列总和不等时则无法计算printf("输入的稀疏矩阵a,b不是行列相等的矩阵。
数据结构实验报告实验五稀疏矩阵运算器
一、引言稀疏矩阵是一个具有大量零元素的矩阵,对于大规模的矩阵来说,如果没有充分利用矩阵的稀疏性质,将会带来很大的存储空间和计算时间上的浪费。
为了解决这个问题,我们需要通过设计一个稀疏矩阵运算器来对稀疏矩阵进行各种运算,以提高计算效率。
二、实验目标本实验的主要目标是设计一个稀疏矩阵运算器,通过实现对稀疏矩阵的加法、乘法和转置等操作,实现对稀疏矩阵的高效运算。
三、设计思路和方法1. 矩阵的表示方式在设计稀疏矩阵运算器时,我们需要选择合适的数据结构来表示稀疏矩阵。
由于稀疏矩阵中大部分元素为零,我们可以采用压缩存储的方法来表示稀疏矩阵。
一种常用的压缩存储方法是使用三元组表示法,即将矩阵的非零元素的值、所在的行号和列号分别存储在一个三元组中。
2. 加法运算稀疏矩阵的加法运算是指将两个稀疏矩阵进行对应位置的相加操作。
在进行稀疏矩阵的加法运算时,首先需要判断两个矩阵的维度是否相同,然后通过遍历两个矩阵的非零元素,将相同位置的元素进行相加得到结果。
3. 乘法运算稀疏矩阵的乘法运算是指将两个稀疏矩阵进行矩阵乘法操作。
在进行稀疏矩阵的乘法运算时,首先需要判断第一个矩阵的列数是否等于第二个矩阵的行数,然后通过遍历两个矩阵的非零元素,按照行和列的顺序对应相乘,再将相乘的结果加到结果矩阵中。
4. 转置运算稀疏矩阵的转置运算是指将矩阵的行和列对换。
在进行稀疏矩阵的转置运算时,只需要将矩阵的非零元素的行号和列号对换即可。
五、实验结果与分析我们在实现稀疏矩阵运算器后,对其进行了测试。
通过测试,我们发现稀疏矩阵运算器能够正确地进行稀疏矩阵的加法、乘法和。
数据结构实验第五实验
实验五稀疏矩阵的快速转置
一、实验目的
熟悉数组的有关概念,掌握稀疏矩阵的三元组存储结构及其快速转置算法。
二、实验内容
键盘任意输入一个稀疏矩阵A(m*n)(也可以随机得产生一个稀疏矩阵),采用三元组存储方法求其转置矩阵B(n*m),并用快速转置算法实现该操作。
三、实验要点及说明
稀疏矩阵的快速转置方法是预先确定好被转置矩阵的每一列的第一个非零元在转置后的目标矩阵三元组中的应有位置。
为了确定相应位置,转置前必须求得稀疏矩阵A的三元组中每列非零元的个数,从而求得每列的第一个非零元在转置矩阵B的三元组中(行)的位置。
为此需要两个辅助数组num和cpot,num[col]表示矩阵A的第col列中非零元的个数,cpot[col]矩阵A的第col列的第一个非零元在矩阵B中的恰当位置,且显然有:
cpot[1]=1;
cpot[col]= cpot[col-1]+ num[col-1] 2≤ col≤ A的列
四、思考题
采用三元组存储实现方法求两个稀疏矩阵的乘积?。
稀疏矩阵计算实验报告
x
r
k 1
= xk + =rk -
p
k k
k
k 1
T
A
p
k
r r = kA Pk P
k
k
T
k
= r k 1 r rk r
k
T
k 1
T
k
P
k 1
r k 1
k
P
k
预优共轭梯度法是将原方程组变形,使其系数矩阵的谱相对集中。简单的说,就是先选 择一个适当的对称正定矩阵 M,使矩阵 M-1A 的谱相对集中,在运用共轭梯度法方法到等价 的方程组
(M
1 2
AM 2 )(M 2 x) M 2 b
1
1
1
上即可。 PCG 法基本格式: Ax b
A c xc
1 1
X CX
bc b
1
x r
k 1
= xk + =rk -
p
k
k
1
k 1
k
A
p =c r
k
k
P
k 1
c 1r
k 1
k
P
k
四、实验内容与步骤: 1、实验内容:依照实验原理编共轭梯度法(CG)和预优共轭梯度法(PCG)的程序。 2、实验步骤: 实验程序如下: 程序代码
东北师范大学
稀疏矩阵计算实验报告
姓名: 学号:
孙洋 2015101763
2015-2016 学年第二学期《稀疏矩阵计算》实验报告
稀疏矩阵计算实验报告
实验名称 姓名 孙洋 年级 稀疏矩阵计算实验 研一 实验 学号 2015101763 指导教师 成绩 李冰玉
数据结构实验稀疏矩阵计算器
‘实验报告题目:稀疏矩阵运算器班级:14电子商务平台建设班完成日期:2015.11.2 学号:姓名:孙少辉学号:姓名:杨德龙学号:姓名:柴益新一:需求分析稀疏矩阵是指那些多数元素为零的矩阵。
利用“稀疏“特点进行存储和计算可以大大节省存储空间,提高计算效率。
实现一个能进行稀疏矩阵基本运算的运算器。
【基本要求】以“带行逻辑链接信息“的三元组顺序表示稀疏矩阵,实现两个矩阵相加、相减和相乘运算。
稀疏矩阵的输入采用三元组表示,而运算结果的矩阵则以通常阵列形式列出。
【项目约束】1.首先应输入矩阵的行数和列数,并判断给出的两个矩阵行、列数对于所要求作的运算是否相匹配。
可设矩阵的行数和列数均不超过20。
2.程序可以对三元组的输入顺序加以限制,例如,按行优先。
注意研究教科书5.3.2节中的算法,以便提高计算效率。
3.在用三元组稀疏矩阵时,相加或相减所得结果矩阵应该另生成,乘积矩阵也可用二维数组存放。
三:详细设计1:数据结构的定义元素类型、变量、指针类型(1)项目数据表:3.2子函数3:函数调用关系无函数调用关系,只有一个主函数四:调试分析三元组顺序的输入规则。
以0 0 0 作为输入的结束信号。
完成实现稀疏矩阵的相加、相减、相乘的运算。
五:用户使用说明(1)首先运行文件系统1.首先定义要运算的第一个稀疏矩阵的行列数定义完成之后输入另一个要运算的稀疏矩阵的行列。
(2)输入信息:如下图所示输入两个矩阵的元素所有输入信息以及运算方法输入完成之后。
回车直接算出结果(3)输出信息:六、源代码/*****项目名称:稀疏矩阵的运算***设计者:杨德龙,柴益新,孙少辉***时间:2015.11.02***实现目标:实现矩阵的加法,减法,乘法;***/#include<stdio.h>#include<windows.h>int main(){//定义二维数组及用到的各种变量int a[20][20];int b[20][20];int c[20][20];int m,n,k,l,i,j,p;int sum;int o;char t;//输入操作printf("请输入第一个矩阵的行列\n");scanf("%d%d",&n,&m); //初始化a数组for(i=0;i<n;i++)for(j=0;j<m;j++)a[i][j]=0;printf("请输入第二个矩阵的行列\n");scanf("%d%d",&k,&l); //初始化b数组for(i=0;i<n;i++)for(j=0;j<m;j++)b[i][j]=0;printf("请用三元组的方式输入第一个矩阵(例1 1 1)(输入0 0 0时结束)\n");while(true){scanf("%d%d%d",&i,&j,&p);if(i==0 && j==0 && p==0)break;elsea[i-1][j-1]=p;}printf("请用三元组的方式输入第二个矩阵(例1 1 1)(输入0 0 0时结束)\n");while(true){scanf("%d%d%d",&i,&j,&p);if(i==0 && j==0 && p==0)break;elseb[i-1][j-1]=p;}printf("请输入执行操作(+或-或*)\n");while(true){getchar();scanf("%c",&t);if(t=='+') //加法运算{{printf("不能进行该运算!!");exit(0); //结束}else{printf("答案为:\n");for(i=0;i<n;i++){for(j=0;j<m;j++){printf("%d ",a[i][j]+b[i][j]);}printf("\n");}exit(0); //结束}}else if(t=='-') //减法运算{{printf("不能进行该运算!!");exit(0); //结束}else{printf("答案为:\n");for(i=0;i<n;i++){for(j=0;j<m;j++){printf("%d ",a[i][j]-b[i][j]);}printf("\n");}exit(0); //结束}}else if(t=='*') //乘法运算{if(m!=k){printf("不能进行该运算!!");exit(0); //结束}else{printf("答案为:\n");for(o=0;o<n;o++){for(i=0;i<l;i++){sum=0;for(j=0;j<m;j++){sum=sum+a[o][j]*b[j][i];}printf("%d ",sum);}printf("\n");}exit(0); //结束}v .. . ..}elseprintf("输入符号错误,重新输入:\n");}return 0; //结束}. . . 资料. .。
稀疏矩阵运算器
} Status DestoyArray(Array &A){ if(!A.base) return ERROR; free(A.base); A.base=NULL; if !(A.bounds) return ERROR; free(A.bounds); A.bounds=NULL; if!(A.constatns) return ERROR; free(A.constants); A.constants=NULL; return OK; } Status Locate(Array A,va_list ap,int &off){ off=0; for(i=0;i< p=""> ind=va_arg(ap,int); if(ind<0||ind>=A.bounds[i]) return OVERFLOW; off+=A.constants[i]*ind; } return OK; } Status Value(Array A,ElemType &e,...){ va_start(ap,e); if((result=Locate(A,ap,off))<=0 return result; e=*(A.base+off); return OK; } Status Assign(Array &A,ElemType e,...){ va_start(ap,e); if((result=Locate(A,ap,off))<=0) return result; *(A.base+off)=e; return OK; }
printf("%5d",p->data[n].e); //控制格式 n++; } else printf("%5d",0); } printf("\n"); } printf("\n"); }
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
if(M.data[p].v+N.data[q].v!=0) //两个稀疏矩阵相加的结果不为 0 {
Q.data[k].row=M.data[p].row; Q.data[k].col=M.data[p].col; Q.data[k].v=M.data[p].v+N.data[q].v;++k; } ++q;++p; } else if(M.data[p].col<N.data[q].col) //第一个稀疏矩阵列数小于第二个稀疏矩阵列数 {
void creat(rtripletable &A) //创建稀疏矩阵 {
int k=1,sum=1,loop,p,t; int num[maxrow+1]; cout<<"请输入矩阵的行数和列数:"<<endl; cout<<"行数:";cin>>A.mu; cout<<"列数:";cin>>A.nu; cout<<"非零元素个数:";cin>>A.tu; cout<<"请按行,列和值的形式输入该矩阵的非零 元.并以全零为结束标记!"<<endl; for(loop=1;loop<=A.tu;loop++) {
|
A、输入矩阵 1
|
|
B、输入矩阵 2
|
|
C、矩阵相加
|
|
D、矩阵相减
|
|
E、矩阵相乘
|
|
F、退出本系统
|
------------------------------------------------------------------------------------------------------请选择所需要的操作功能(A,B,C,D,E,F) :
指导教师 批阅及签名
三、实验报告内容
2007 年 5 月 30 日
实验报告内容原则上应包括主要实验步骤、实验数据计算(实验操作)结果、实验结果 (疑问)分析等项目。 【主程序模块】:
void main() {
初始化; do{
接受命令; 处理命令; }while(命令!=“退出”); } 【功能模块调用关系图】
误。 【用户手册】
1 、 本 程 序 的 运 行 环境为 Windows me 下 的 Microsofe VC++ 6.0, 执行文 件 为 : xishujuzhen.cpp。
2、进入演示程序后即显示文本方式的用户界面:
-------------------------------------------------------------------------------------------------------
基本操作: CreateSMatrix(&M); //操作结果:创建稀疏矩阵 M. Print SMatrix(M); //初始化条件: 稀疏矩阵 M 存在. //操作结果:输出稀疏矩阵 M. AddSMatrix(M,N,&Q); //初始化条件: 稀疏矩阵 M 与 N 的行数和列数对应相等. //操作结果:求稀疏矩阵的和 Q=M+N. SubSMatrix(M,N,&Q); //初始化条件: 稀疏矩阵 M 与 N 的行数和列数对应相等. //操作结果:求稀疏矩阵的差 Q=M-N. MultSMatrix(M,N,&Q); //初始化条件: 稀疏矩阵 M 的列数等于 N 的行数. //操作结果:求稀疏矩阵的乘积 Q=M*N.
Q.data[k]=M.data[p]; //把 M 中的所有信息都赋给 Q ++p;++k; } else //第一个稀疏矩阵列数大于第二个稀疏矩阵的列数 { Q.data[k]=N.data[q];++q;++k; } } else if(M.data[p].row<N.data[q].row) //第一个稀疏矩阵行列数小于第二个稀疏矩阵行数 { Q.data[k]=M.data[p];++p;++k; } else //第一个稀疏矩阵行列数小于第二个稀疏矩阵行数 {
Windows 2000,Visual C++ 6.0 或 WINTC 【概要设计】
ADT Array { 数据对象: D-1}
数据关系: R = { ROW, COL } ROW = {<ai,j,ai+1,j>| 0≤i≤b1-2, 0≤j≤b2-1} COL = {<ai,j,ai,j+1>| 0≤i≤b1-1, 0≤ j≤b2-2}
主程序模块
创建稀疏矩阵模块
运算稀疏矩阵模块
【详细设计】
打印稀疏矩阵模块 稀疏矩阵运算器
矩阵相加
矩阵相减
输入矩阵 1
输入矩阵 1
输入矩阵 2
输入矩阵 2
计算结果
计算结果
typedef struct{ int row; //行数 int col; //列数 int v; //非零元素值
}triplenode;
3、进入界面后,只要选择数字命令按“回车键”就行。 4、接受其他命令后即执行相应的操作和相应的结果。 实验报告评分:
注:1、如有个别实验的实验报告内容多,实验报告册页面不够写,或有识图,画图要求的,学生应根据实 验指导老师要求另附相同规格的纸张并粘贴在相应的“实验报告册”中。
2、实验报告册属教学运行材料,院系(中心)应按有关规定归档保管。
矩阵相乘 输入矩阵 1 输入矩阵 2 计算结果
退出本系统
typedef struct{ triplenode data[maxsize+1]; //非零元三元组 int rowtab[maxrow+1]; //各行第一个非零元的位置表 int mu,nu,tu; //矩阵的行数、列数和非零元个数
}rtripletable; void creat(rtripletable &A) //创建稀疏矩阵 void print(rtripletable A) //输出稀疏矩阵 int addsmatrix(rtripletable M, rtripletable N) //矩阵相加 int subsmatrix(rtripletable M, rtripletable N) //稀疏矩阵相减 void multsmatrix(rtripletable M, rtripletable N, rtripletable &Q)
} ADT Array
【疑问】
(这部分内容因人而异,也可不写)
实验预习评分:
二、实验原始(数据)记录
实 验 时 间: 2007 年 5 月 30 日(星期 三 第 7,8 节) 实验同组人 : 如有实验实验数据表格,学生在实验预习时应画好实验数据表格,供实验填写数据。 请选择所需要的操作功能(A,B,C,D,E,F)A 请输入矩阵的行数和列数: 行数 2 列数 2 非零元素个数:2 请按行,列和值的形式输入该矩阵的非零元.并以全零为结束标记! 129 2 1 -1 请选择所需要的操作功能(A,B,C,D,E,F):B 请输入矩阵的行数和列数: 行数 2 列数 2 非零元素个数:2 请按行,列和值的形式输入该矩阵的非零元.并以全零为结束标记! 1 1 -1 2 1 -3 请选择所需要的操作功能(A,B,C,D,E,F):C 加法结果为: |-1 9| |-4 0| 请选择所需要的操作功能(A,B,C,D,E,F):D 减法结果为: |1 9| |2 0| 请选择所需要的操作功能(A,B,C,D,E,F):E 乘法结果为: |-27 0| |1 0|
//稀疏矩阵相乘
【调试分析】(这部分内容因人而异)
1、由于开始对顺序存储的知识还不熟识,在三元组的存储和运用会导致算法低效。 2、做到存储的时候,开始时不知道怎样存储三元组,和不知如何去运用它的行数,
列数,非零元素。 3、在使用选择和循环时,有时因为自己的粗心,把循环的条件弄错了。 4、做本程序用到了数组的知识,有时一有不懂的东西又只能打开书来看。 5、开始时没有把矩阵的加法和减法的情况考虑全面,导致输出的时候会出现简单的错
int addsmatrix(rtripletable M, rtripletable N) //矩阵相加 {
if(M.mu!=N.mu) //行数相等才能相加 cout<<"出错"; rtripletable Q;Q.mu=M.mu;Q.nu=N.nu; int p,q,k; p=1;q=1;k=1; while(p<=M.tu&&q<=N.tu) //两个稀疏矩阵存在 { if(M.data[p].row==N.data[q].row) //两个稀疏矩阵的行数相等 { if(M.data[p].col==N.data[q].col) //两个稀疏矩阵的列数相等 {
int result[maxrow+1][maxrow+1]; //定义一个二维数组 int loop1,loop2; for(loop1=1;loop1<=A.mu;loop1++) for(loop2=1;loop2<=A.nu;loop2++) result[loop1][loop2]=0; //初始化为 0 for(loop1=1;loop1<=A.tu;loop1++) result[A.data[loop1].row][A.data[loop1].col]=A.dat a[loop1].v; for(loop1=1;loop1<=A.mu;loop1++) { cout<<"|"; for(loop2=1;loop2<=A.nu;loop2++) cout<<result[loop1][loop2]<<""; //输出所做运算的结果 cout<<"|"<<endl; } }