《数据结构 课程设计》稀疏矩阵实验报告
数据结构-稀疏矩阵实验报告
实验报告
课程 学号 数据结构 姓名 实验名称 实验四 稀疏矩阵 实验日 期: 2012/11/12
实验四 实验目的:稀疏矩阵1.熟悉数组在计算机内存中存储的实现机制; 2.熟练并掌握数组的基本运算; 3.熟悉并掌握特殊矩阵的压缩存储方法及压缩存储下的矩阵的运算; 3.熟悉稀疏矩阵的“三元组表”和“十字链表”存储结构。
if(i<=j) { for(k=1;k<=n;k++) { if(i<=k) p=k*(k-1)/2+i-1; else p=n*(n+1)/2; if(j>=k) q=j*(j-1)/2+k-1; else q=n*(n+1)/2; sum=sum+a[p]*b[q]; } c[j*(j-1)/2+i-1]=sum; sum=0; } else c[n*(n+1)/2]=0; } } void print(int a[], int n) { int i,j; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(i<=j) printf("%5d", a[j*(j-1)/2+i-1]); else printf("%5d", a[n*(n+1)/2]); } printf("\n"); } } void main() { int u[]={1,2,4,3,5,6,0}; int v[]={10,20,40,30,50,60,0}; int c[7], n=3; add(u,v,c,n); printf("C=A+B=\n"); print(c,n);
数据结构实验报告三稀疏矩阵的运算
数据结构实验报告三稀疏矩阵的运算实验课程名称数据结构课程设计专业班级学⽣姓名学号指导教师2012 ⾄ 2013 学年第⼀学期第 1 ⾄ 18 周⽬录实验题⽬:稀疏矩阵的运算 (3)⼀:概述 (3)⼆:系统分析 (3)三:概要设计 (3)四:详细设计 (4)五:运⾏与测试 (9)六:总结与⼼得 (9)实验题⽬:稀疏矩阵的运算⼀:概述本实验设计主要实现在⼗字链表存储结构输⼊稀疏矩阵,并对稀疏矩阵进⾏相加操作,最后输出运算结果。
⼆:系统分析本实验要求设计函数在⼗字链表结构下建⽴稀疏矩阵并初始化,在创建稀疏矩阵时,需要设计在⼗字链表下创建稀疏矩阵,在输⼊出现错误时,能够对错误进⾏判别处理,初始化稀疏矩阵都为空值。
在设计输出稀疏矩阵的值的函数时,根据情况编制函数,才能准确的输出稀疏矩阵。
在对稀疏矩阵进⾏初始化时,只输⼊⾮零元素的值和它所在的所在⾏及所在列。
在对稀疏矩阵输出时,以矩阵的完整形式输出。
除此之外还要求设计相加对两个矩阵进⾏运算,并输出最终的稀疏矩阵,定义相应的矩阵类型⽤于存放两个矩阵操作后的结果矩阵,这个结果矩阵的⾏、列数需要综合多⽅⾯情况来确定。
这些函数也是整个程序的难点,需要灵活运⽤数组及指针的特点。
三:概要设计⼗字链表结构体定义:typedef struct sex{int row,col,val; //⾮零元素的⾏、列下标及值struct sex *right,*dowm; //该⾮零元素所在⾏表和列表的后继元素}Node;矩阵的加法:此功能在⼗字链表存储结构下,由函数void addition(Node *cp1, Node *cp2, Node *cp3)实现。
当⽤户选择该功能,系统即提⽰⽤户初始化要进⾏加法的两个矩阵的信息。
然后进⾏加法,最后输出结果。
四:详细设计#include#includetypedef struct sex{int row,col,val; //⾮零元素的⾏、列下标及值struct sex *right,*dowm; //该⾮零元素所在⾏表和列表的后继元素}Node;Node * Init(int m, int n){int t,i;Node *cp;t=(m>=n)?m:n;cp=(Node *)malloc( (t+1)*sizeof(Node) ); //开辟⼀串连续的内存空间(*cp).row=m;(*cp).col=n;(*cp).val=t; //此表头结点的值域⽤来记录⾏列的最⼤值,以便于后⾯的开辟空间for(i=1;i<=t;i++){cp[i].right=cp+i;cp[i].dowm=cp+i; //构成带表头结点的空循环单链表}return cp;}void CreatCrossList(Node *cp){int t,i;Node *s,*temp;printf("请输⼊⾮零元素的个数N:");scanf("%d",&t);printf("\n请输⼊其对应坐标及元素值:\n");for(i=0;i{s=(Node *)malloc( sizeof(Node));scanf("%d%d%d",&s->row,&(*s).col,&s->val);temp=cp+s->row;if( temp->right!=cp+s->row )while( temp->right!=cp+s->row && temp->right->col<=s->col )temp=temp->right;s->right=temp->right;temp->right=s; //修改⾏链表插⼊位置temp=cp+s->col;if( temp->dowm!=cp+s->col )while( temp->dowm!=cp+s->col && temp->dowm->row<=s->row )temp=temp->dowm;s->dowm=temp->dowm;temp->dowm=s; //修改列链表插⼊位置}}void output(Node *cp){int i;Node *temp;printf("\n稀疏矩阵如下:\n");for(i=1;i<=cp->row;i++){temp=cp+i;while( temp->right!=cp+i ){printf("(%d,%d %d)",temp->right->row,temp->right->col,temp->right->val); temp=temp->right;}printf("\n");}}void Insert(Node *cp, Node *s){//此插⼊函数的作⽤是:⽣成⽬标矩阵Node *temp;temp=cp+s->row; //修改⾏链表指针if( temp->right!=cp+s->row )while( temp->right!=cp+s->row && temp->right->col<=s->col ) temp=temp->right;s->right=temp->right;temp->right=s;temp=cp+s->col; //修改列链表指针if( temp->dowm!=cp+s->col )while( temp->dowm!=cp+s->col && temp->dowm->row<=s->row ) temp=temp->dowm;s->dowm=temp->dowm;temp->dowm=s;}void addition(Node *cp1, Node *cp2, Node *cp3){int i;Node *w,*p,*q;for( i=1; i<=cp2->row && i<=cp3->row; i++){p=cp2+i;q=cp3+i;while( p->right!=cp2+i && q->right!=cp3+i ){w=(Node *)malloc( sizeof(Node) );w->row=p->right->row;if( p->right->col==q->right->col ){w->col=p->right->col;w->val=p->right->val+q->right->val; //相同位置上的元素值相加p=p->right;q=q->right;if( w->val )Insert(cp1,w); //把⾮零元插⼊到⽬标矩阵中}else if( p->right->colright->col ){w->col=p->right->col;w->val=p->right->val;p=p->right;Insert(cp1,w); //把cp2中的⾮零元插⼊到⽬标矩阵中}else{w->col=q->right->col;w->val=q->right->val;q=q->right;Insert(cp1,w); //把cp2中的⾮零元插⼊到⽬标矩阵中}}if( p->right==cp2+i )while( q->right!=cp3+i ){w=(Node *)malloc( sizeof(Node) );w->row=q->right->row;w->col=q->right->col;w->val=q->right->val;q=q->right;Insert(cp1,w); //把cp3中剩余的⾮零元插⼊⽬标矩阵中} else if( q->right==cp3+i )while( p->right!=cp2+i ){w=(Node *)malloc( sizeof(Node) );w->row=p->right->row;w->col=p->right->col;w->val=p->right->val;p=p->right;Insert(cp1,w); //把cp2中剩余的⾮零元插⼊到⽬标矩阵中} else; //两个矩阵同⼀⾏中同时结束}if( i>cp2->row)while(i<=cp3->row){//把cp3中剩余⾏中的⾮零元插⼊到⽬标矩阵中q=cp3+i;while( q->right!=cp3+i ){w=(Node *)malloc( sizeof(Node) );w->row=q->right->row;w->col=q->right->col;w->val=q->right->val;q=q->right;Insert(cp1,w);}i++; //继续下⼀⾏}else if(i>cp3->row)while( i<=cp2->row ){p=cp2+i;while( p->right!=cp2+i ){w=(Node *)malloc( sizeof(Node) );w->row=p->right->row;w->col=p->right->col;w->val=p->right->val;p=p->right;Insert(cp1,w);}i++; //继续下⼀⾏}}int main(){Node *cp1, *cp2, *cp3;int a, b;printf("\t\t\t*****稀疏矩阵的加法*****\n\n");printf("请输⼊cp2的⾏、列数:");scanf("%d%d",&a,&b);cp2=Init(a,b);printf("请输⼊cp3的⾏、列数:");scanf("%d%d",&a,&b);cp3=Init(a,b);a=cp2->row>=cp3->row?cp2->row:cp3->row;b=cp2->col>=cp3->col?cp2->col:cp3->col;cp1=Init(a,b); //开始初始化结果矩阵printf("\n\t>>>>>>>创建稀疏矩阵cp2\n");CreatCrossList(cp2);printf("\n\t>>>>>>>创建稀疏矩阵cp3\n");CreatCrossList(cp3);output(cp2);output(cp3);addition(cp1,cp2,cp3);printf("\n\n相加后的"); output(cp1);return 0;}五:运⾏与测试进⾏数据测试六:总结与⼼得⼗字链表作为存储结构表⽰随机稀疏矩阵,进⾏两矩阵的相加运算,所以⾸先要定义⼀个⼗字链表作为存储结构。
稀疏矩阵数据结构实验报告
目录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. 掌握稀疏矩阵的基本操作,包括转置、加法、减法和乘法。
3. 通过编程实践,提高对数据结构和算法的理解和应用能力。
二、实验环境1. 编程语言:C语言2. 开发环境:Visual Studio 20193. 操作系统:Windows 10三、实验内容1. 稀疏矩阵的三元组表示及其实现2. 稀疏矩阵的转置3. 稀疏矩阵的加法、减法和乘法四、实验步骤1. 稀疏矩阵的三元组表示及其实现(1)定义稀疏矩阵的三元组结构体:```ctypedef struct {int row; // 行号int col; // 列号double val; // 非零元素值} Triple;```(2)定义稀疏矩阵结构体:typedef struct {int rows; // 矩阵行数int cols; // 矩阵列数int nums; // 非零元素个数Triple data; // 非零元素的三元组数组} SparseMatrix;```(3)编写函数实现稀疏矩阵的创建:```cvoid createSparseMatrix(SparseMatrix sm, int rows, int cols, int nums) { sm->rows = rows;sm->cols = cols;sm->nums = nums;sm->data = (Triple )malloc(nums sizeof(Triple));}```(4)编写函数实现稀疏矩阵的销毁:```cvoid destroySparseMatrix(SparseMatrix sm) {free(sm->data);sm->data = NULL;}2. 稀疏矩阵的转置(1)编写函数实现稀疏矩阵的转置:```cvoid transposeSparseMatrix(SparseMatrix src, SparseMatrix dst) {dst->rows = src->cols;dst->cols = src->rows;dst->nums = src->nums;dst->data = (Triple )malloc(src->nums sizeof(Triple));for (int i = 0; i < src->nums; i++) {dst->data[i].row = src->data[i].col;dst->data[i].col = src->data[i].row;dst->data[i].val = src->data[i].val;}}```3. 稀疏矩阵的加法、减法和乘法(1)编写函数实现稀疏矩阵的加法:```cvoid addSparseMatrix(SparseMatrix sm1, SparseMatrix sm2, SparseMatrix result) {result->rows = sm1->rows;result->cols = sm1->cols;result->nums = 0;for (int i = 0; i < sm1->nums; i++) {for (int j = 0; j < sm2->nums; j++) {if (sm1->data[i].row == sm2->data[j].row && sm1->data[i].col == sm2->data[j].col) {if (sm1->data[i].val + sm2->data[j].val != 0) {result->data[result->nums++] = sm1->data[i];result->data[result->nums - 1].val += sm2->data[j].val;}}}}}```(2)编写函数实现稀疏矩阵的减法:```cvoid subSparseMatrix(SparseMatrix sm1, SparseMatrix sm2, SparseMatrix result) {result->rows = sm1->rows;result->cols = sm1->cols;result->nums = 0;for (int i = 0; i < sm1->nums; i++) {for (int j = 0; j < sm2->nums; j++) {if (sm1->data[i].row == sm2->data[j].row && sm1->data[i].col == sm2->data[j].col) {if (sm1->data[i].val - sm2->data[j].val != 0) {result->data[result->nums++] = sm1->data[i];result->data[result->nums - 1].val -= sm2->data[j].val;}}}}}```(3)编写函数实现稀疏矩阵的乘法:```cvoid mulSparseMatrix(SparseMatrix sm1, SparseMatrix sm2, SparseMatrix result) {result->rows = sm1->rows;result->cols = sm2->cols;result->nums = 0;for (int i = 0; i < sm1->nums; i++) {for (int j = 0; j < sm2->nums; j++) {if (sm1->data[i].col == sm2->data[j].row) {double sum = 0;for (int k = 0; k < sm1->nums; k++) {if (sm1->data[k].col == sm2->data[j].row) {sum += sm1->data[k].val sm2->data[j].val;}}if (sum != 0) {result->data[result->nums++] = sm1->data[i];result->data[result->nums - 1].val = sum;}}}}}```五、实验结果与分析1. 通过编程实现稀疏矩阵的基本操作,验证了算法的正确性。
数据结构实验报告稀疏矩阵运算
教学单位计算机科学与技术学生学号************数据结构课程设计报告书题目稀疏矩阵运算器学生姓名秦豹专业名称软件工程指导教师李志敏实验目的:深入研究数组的存储表示和实现技术,熟悉广义表存储结构的特性。
需要分析:稀疏矩阵是指那些多数元素为零的矩阵。
利用“稀疏”特点进行存储和计算可以大大节省存储空间,提高计算效率。
实现一个能进行稀疏矩阵基本运算的运算器。
要求以带“行逻辑链接信息”的三元组顺序表存储稀疏矩阵,实现两矩阵的相加、相减、相乘等运算。
输入以三元组表示,输出以通常的阵列形式列出。
软件平台: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。
课程设计实验报告 稀疏矩阵应用
数据结构课程设计《数据结构》课程设计一.题目:稀疏矩阵应用(限1 人完成)要求:实现三元组,十字链表下的稀疏矩阵的加、转、乘的实现。
(1)稀疏矩阵的存储(2)稀疏矩阵加法(3)矩阵乘法(4)矩阵转置二.算法思想描述:1.需求分析(1)设计函数建立稀疏矩阵,初始化值。
(2)设计函数输出稀疏矩阵的值。
(3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。
(4)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。
(5)构造函数进行稀疏矩阵的转置,并输出结果。
(6)退出系统。
1.算法概述:首先用两个结构体来定义十字链表元素:typedef struct OLNode{int i,j;int e;struct OLNode *right,*down;}OLNode,*OLink;OLNode结构为链表结点,i,j,e分别表示稀疏矩阵中元素的行,列和值。
typedef struct {int mu,nu,tu; //行数mu,列数nu,非零元素的个数tuOLink *rhead,*chead;}CrossList;CrossList结构用于连接起各个结点,mu,nu,tu分别表示整个矩阵的行数列数和非零元素的个数。
整个程序包含CreateSMatix_OL(用于创建十字链表),SMatrix_ADD(十字链表相加),ShowMAtrix(十字链表显示),MultSMatrix_OL(十字链表相乘),TurnSMatrix_OL(十字链表转置),DestroySMatrix_OL(十字链表销毁)六个函数。
CreateSMatix_OL的功能如下:首先输入稀疏矩阵的行数,列数,非零元素的个数,为*rhead和*chead分配内存空间,并将十字链表中节点初始化为NULL。
然后依次输入非零元素的行,列,值,以0 0 0为结尾结束链表的连接和while循环。
SMatrix_ADD 的功能如下:在初始化稀疏矩阵后选择十字链表相加会提示输入另一个稀疏矩阵,连接结束后SMatrix_ADD 函数以循环的方式比较非零元素是否为同一行列,如果是则两值相加,如果不是则把第二个元素加入链表中。
数据结构-稀疏矩阵-实验报告与代码
一.需求分析输入要求:稀疏矩阵的行、列和非零元素个数输出要求:稀疏矩阵的转置、加法、减法、乘法二.算法设计本程序中采用的数据模型,用到的抽象数据类型的定义,程序的主要算法流程及各模块之间的层次调用关系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)三元组表单元模块:实现矩阵抽象数据类型。
数据结构_实验四_字符串、稀疏矩阵实验
实验编号:4四川师大《数据结构》实验报告2016年11月12日实验四字符串、稀疏矩阵实验_一.实验目的及要求(1)熟悉字符串类型的实现方法,并完成串的一些基本操作;(2)掌握稀疏矩阵的三元组顺序表存储表示,并实现矩阵的转置运算。
二.实验内容(1)编程实现两个串S1和S2的比较。
(要求自己设计串的存储结构,并编写比较函数,不要调用系统提供的函数)(2)编程实现稀疏矩阵的三元组顺序表示方法及基本操作的实现(建立、输出、转置等)。
(3)编程实现稀疏矩阵的十字链表存储表示及基本操作的实现(建立、输出等)。
注:(2)必做,(1)(3)选做。
三.主要仪器设备及软件(1)PC机(2)Dev C++ ,Visual C++, VS2010等四.实验主要流程、基本操作或核心代码、算法片段(该部分如不够填写,请另加附页)(1)编程实现两个串S1和S2的比较。
(要求自己设计串的存储结构,并编写比较函数,不要调用系统提供的函数)➢代码部分://Main.cpp:#include"SString.h"int main(){SString T1,T2;int i,n;T1[0]=T2[0]=0;cout<<"input T1 size:";cin>>n;T1[0]=n;cout<<"input T1 data:";for(i=1;i<=n;i++){cin>>T1[i];}cout<<"input T2 size:";cin>>n;T2[0]=n;cout<<"input T2 data:";for(i=1;i<=n;i++){cin>>T2[i];}cout<<"T1"<<Compare(T1,T2)<<"T2"<<endl;return 0;}//SString.cpp:#include"SString.h"char Compare(SString T1,SString T2){if(T1[0]>T2[0]){return '>';}else if(T1[0]<T2[0]){return '<';}else{for(int i=1;i<=T1[0];i++){if(T1[i]>T2[i]){return '>';}else if(T1[i]<T2[i]){return '<';}}}return '=';}//SString.h:#include<iostream>using namespace std;const int MAX=255;typedef unsigned char SString[MAX+1];char Compare(SString T1,SString T2);➢运行结果:(2)编程实现稀疏矩阵的三元组顺序表示方法及基本操作的实现(建立、输出、转置等)。
《数据结构 课程设计》稀疏矩阵实验报告
目录一、概述 (1)二、系统分析 (1)三、概要设计 (1)(1)主界面的设计: (2)(2)系数矩阵的存储 (2)(3)具体实现流程图: (3)四、详细设计 (4)(2)稀疏矩阵的相加: (5)五、运行与测试 (8)六、总结与心得 (9)参考文献 (9)源代码 (9)一、概述稀疏矩阵的加法运算,既将稀疏矩阵A和B,他均为m行n列,分别以数组的形式存放在A和B中,实现A+B=C,将所得的结果存放在C数组中。
二、系统分析稀疏矩阵的保存:以一位数组顺序存放非零元素的行号、列号和数值,行号为-1作为结束符。
以三个一维数组存放一个系数矩阵中的一个非零元素,为零额元素则不保存。
用一个二重循环来实现判断每个系数矩阵的非零元素是否为零,不为零,就将其行列下标和其值存入一维数组中稀疏矩阵的相加:用循环来判断存储A何B稀疏矩阵的两个一维数组中的行列下标是否相等和其大小关系。
若相等,则将两个一维数组的第三个元素的值相加存入新的数组C里,行列下标不变的存入进去;若A的列小于B的列,则将A的三个元素直接存入C中;若B的列小于A的列,则将B的三个元素村日C中;若A的行小于B的行,则将A的三个元素存入C中;若A的行大于B的行,则将B存入C中。
三、概要设计(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如下: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。
数据结构稀疏矩阵基本运算实验报告
课程设计课程:数据结构题目:稀疏矩阵4 三元组单链表结构体(行数、列数、头) 矩阵运算重载运算符优班级:姓名:学号:设计时间:2010年1月17日——2010年5月XX日成绩:指导教师:楼建华一、题目二、概要设计1.存储结构typedef struct{int row,col;//行,列datatype v;//非0数值}Node;typedef struct{Node data[max];//稀疏矩阵int m,n,t;//m 行,n 列,t 非0数个数……2.基本操作⑴istream& operator >>(istream& input,Matrix *A)//输入⑵ostream& operator <<(ostream& output,Matrix *A){//输出⑶Matrix operator ~(Matrix a,Matrix b)//转置⑷Matrix operator +(Matrix a,Matrix b)//加法⑸Matrix operator -(Matrix a,Matrix b)//减法⑹Matrix operator *(Matrix a,Matrix b)//乘法⑺Matrix operator !(Matrix a,Matrix b)//求逆三、详细设计(1)存储要点position[col]=position[col-1]+num[col-1];三元组表(row ,col ,v)稀疏矩阵((行数m ,列数n ,非零元素个数t ),三元组,...,三元组)1 2 3 4 max-1(2)乘法运算要点已知稀疏矩阵A(m1× n1)和B(m2× n2),求乘积C(m1× n2)。
稀疏矩阵A、B、C及它们对应的三元组表A.data、B.data、C.data如图6所示。
由矩阵乘法规则知:C(i,j)=A(i,1)×B(1,j)+A(i,2)×B(2,j)+…+A(i,n)×B(n,j)=这就是说只有A(i,k)与B(k,p)(即A元素的列与B元素的行相等的两项)才有相乘的机会,且当两项都不为零时,乘积中的这一项才不为零。
稀疏矩阵实验报告
一、实验目的1. 理解稀疏矩阵的概念和特点。
2. 掌握稀疏矩阵的三元组表示方法。
3. 熟悉稀疏矩阵的基本运算,如转置、加法、减法等。
4. 提高编程能力和问题解决能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 2019三、实验内容1. 稀疏矩阵的三元组表示- 设计稀疏矩阵的三元组存储结构。
- 编写函数实现稀疏矩阵的三元组表示。
2. 稀疏矩阵的基本运算- 实现稀疏矩阵的转置。
- 实现稀疏矩阵的加法、减法。
- 实现稀疏矩阵的乘法。
3. 实验结果分析- 对实验结果进行分析,比较稀疏矩阵与普通矩阵运算的效率。
四、实验步骤1. 稀疏矩阵的三元组表示- 定义稀疏矩阵的三元组存储结构,包括行号、列号和元素值。
- 编写函数实现稀疏矩阵的三元组表示,包括读取稀疏矩阵的三元组数据、构建稀疏矩阵的三元组表示等。
2. 稀疏矩阵的基本运算- 实现稀疏矩阵的转置,包括交换行号和列号、重新排序等。
- 实现稀疏矩阵的加法、减法,包括遍历两个稀疏矩阵的三元组,计算对应元素的加法或减法结果。
- 实现稀疏矩阵的乘法,包括遍历两个稀疏矩阵的三元组,计算对应元素的乘法结果。
3. 实验结果分析- 对实验结果进行分析,比较稀疏矩阵与普通矩阵运算的效率。
- 分析实验结果,得出稀疏矩阵运算的优缺点。
五、实验结果1. 稀疏矩阵的三元组表示- 读取稀疏矩阵的三元组数据,构建稀疏矩阵的三元组表示。
2. 稀疏矩阵的基本运算- 实现稀疏矩阵的转置,包括交换行号和列号、重新排序等。
- 实现稀疏矩阵的加法、减法,包括遍历两个稀疏矩阵的三元组,计算对应元素的加法或减法结果。
- 实现稀疏矩阵的乘法,包括遍历两个稀疏矩阵的三元组,计算对应元素的乘法结果。
3. 实验结果分析- 稀疏矩阵运算效率比普通矩阵运算高,尤其在稀疏程度较高的矩阵上。
- 稀疏矩阵运算的缺点是存储空间较大,且运算过程中需要频繁进行数据交换。
数据结构实验报告实验五稀疏矩阵运算器
一、引言稀疏矩阵是一个具有大量零元素的矩阵,对于大规模的矩阵来说,如果没有充分利用矩阵的稀疏性质,将会带来很大的存储空间和计算时间上的浪费。
为了解决这个问题,我们需要通过设计一个稀疏矩阵运算器来对稀疏矩阵进行各种运算,以提高计算效率。
二、实验目标本实验的主要目标是设计一个稀疏矩阵运算器,通过实现对稀疏矩阵的加法、乘法和转置等操作,实现对稀疏矩阵的高效运算。
三、设计思路和方法1. 矩阵的表示方式在设计稀疏矩阵运算器时,我们需要选择合适的数据结构来表示稀疏矩阵。
由于稀疏矩阵中大部分元素为零,我们可以采用压缩存储的方法来表示稀疏矩阵。
一种常用的压缩存储方法是使用三元组表示法,即将矩阵的非零元素的值、所在的行号和列号分别存储在一个三元组中。
2. 加法运算稀疏矩阵的加法运算是指将两个稀疏矩阵进行对应位置的相加操作。
在进行稀疏矩阵的加法运算时,首先需要判断两个矩阵的维度是否相同,然后通过遍历两个矩阵的非零元素,将相同位置的元素进行相加得到结果。
3. 乘法运算稀疏矩阵的乘法运算是指将两个稀疏矩阵进行矩阵乘法操作。
在进行稀疏矩阵的乘法运算时,首先需要判断第一个矩阵的列数是否等于第二个矩阵的行数,然后通过遍历两个矩阵的非零元素,按照行和列的顺序对应相乘,再将相乘的结果加到结果矩阵中。
4. 转置运算稀疏矩阵的转置运算是指将矩阵的行和列对换。
在进行稀疏矩阵的转置运算时,只需要将矩阵的非零元素的行号和列号对换即可。
五、实验结果与分析我们在实现稀疏矩阵运算器后,对其进行了测试。
通过测试,我们发现稀疏矩阵运算器能够正确地进行稀疏矩阵的加法、乘法和。
稀疏矩阵的应用
ta[ta1->td].p=i;
ta[ta1->td].q=j;
ta[ta1->td].x=a[i][j];
ta1->td++;
}
ta1->md=n;
ta1->nd=m;
}
/*转置*/
void transition (tabletype *ta1, tabletype *tb1, List ta[],List tb[])
4.依次取A中的每一个非零元素对应的三元组;
2.1确定该元素在B中的下标pb;
2.2将该元素的行号列号交换后存入B中pb的位置;
2.3预置该元素所在列的下一个元素的存放位置;
具体要定义如下若干个函数:
void setup()初始化非零元的个数
void transition()转置函数
void input()输入函数
{ for(j=0;j<m;j++)
cout<<a[i][j]<<" ";
cout<<"\n";
}
}
/*三元组顺序表输出*/
void print2(List a[],int nn)
{
int i;
cout<<"\t行号\t列号\t元素值\n";
for(i=0; i<nn;i++)
cout<<" "<<a[i].p<<" "<<a[i].q<<" "<<a[i].x<<" "<<"\n";
稀疏矩阵课程设计实验报告
数据结构课程设计学院:信息科学与工程学院专业:计算机科学与技术班级:计算机1108学号:学生姓名:指导教师:2013 年 3 月 10 日稀疏矩阵一、实验内容基本要求:1.以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现两个矩阵相加、想减、相乘的运算。
2.稀疏矩阵的输入形式采用三元组表表示,而运算结果则以通常的阵列形式输出选作内容:1.按书中的描述方法,以十字链表表示稀疏矩阵2.增添矩阵求逆的运算,包括不可求逆的情况。
在求逆之前,先将稀疏矩阵的内容表示改为十字链表…二、数据结构设计三元组结构体定义如下:#include <stdio.h>#include <stdlib.h>#define MAX 100typedef struct{int i,j;int e;}Triple;struct juzhen{Triple data[MAX+1];int first[MAX+1];int mv,nv,tv;};十字链表结构定义如下#include<stdio.h>#include<stdlib.h>#include<conio.h>typedef int ElemType;typedef struct CLNode{int row ;int col;ElemType fenzi;ElemType fenmu;CLNode * right;CLNode * down;}CLNode;typedef struct{CLNode ** rhead;CLNode ** chead;int ru;int lu;int tu;}CrossList;三、算法设计1.三元组表构建稀疏矩阵的定义如下:ADT Matrix{数据对象:D={a ij|i=1,2,…,m; j=1,2,…,n;a ij∈ElemSet, m和n分别为矩阵的行数和列数}数据关系:R={Row,Col }Row={﹤a i,j, a i,j+1﹥| 1≤i≤m, 1≤j≤n-1}Col = {﹤a i,j, a i+1,j﹥| 1≤i≤m-1, 1≤j≤n}基本操作:ChuangJian (XiShu &M)操作结果:创建稀疏矩阵矩阵TMShuChu(XiShu Q)操作结果:通常形式输出稀疏矩阵AddMatrix(XiShu M,XiShu N,XiShu *Q)操作结果:稀疏矩阵的加法运算:void JianMatrix(XiShu M,XiShu N,XiShu *Q)操作结果:稀疏矩阵的减法运算void ChengMatrix(XiShu M,XiShu N,XiShu *Q)操作结果:稀疏矩阵的乘法运算}ADT Matrix;2 十字链表创建稀疏矩阵的定义如下:ADT SparseMatrix{数据对象 D={a ij|i=1,2,3……m,j=1,2,3……n;a ij属于ElemSet,m和n分别是稀疏矩阵的行数和列数}数据关系 R={ Row, Col }Row={<a ij,a ij+1>|1<=i<=m,1<=j<=n-1}Col={<a ij,a i+1j>|1<=i<=m-1,1<=j<=n}基本操作:void Input( CrossList &D )操作结果:十字链表创建稀疏矩阵int Determinant( const CrossList &D ,int row , int line )操作结果:求稀疏矩阵行列式的值void Reduction( int &fenzi, int &fenmu )操作结果:分子分母约分CrossList *InverseMatrix( const CrossList &D )操作结果:求稀疏矩阵的逆矩阵void Output( const CrossList *E )操作结果:十字邻接矩阵的输出}ADT SparseMatrix3.1 功能模块图本功能分为四个模块3.2 算法思路3.2.1实现方法列出系统中的所有函数并说明函数的功能void main() //三元组表法和十字链表的主函数int ChuangJian(XiShu *M) //三元组表法创建稀疏矩阵void ShuChu(XiShu Q) //三元组表法输出稀疏矩阵void AddMatrix(XiShu M,XiShu N,XiShu *Q)//三元组表法实现相加功能void JianMatrix(XiShu M,XiShu N,XiShu *Q)//三元组表法实现相减功能void ChengMatrix(XiShu M,XiShu N,XiShu *Q)//三元组表法实现相乘功能int Determinant(CrossList &D ,int row ,int line )//行列式求值void Reduction( int &fenzi, int &fenmu ) //分子分母约分void Input( CrossList &D ) //十字链表输入函数CrossList *InverseMatrix(CrossList &D)//求稀疏矩阵的逆矩阵void Output( const CrossList *E ) //十字链表输出函数3.2.2 设计思想稀疏矩阵加法运算思路:首先判断两个矩阵行数列数是否相等,比较两个矩阵中不为0的元素的行数i 及列数j,将i与j都相等的前后两个元素值e相加,保持i,j不变储存在新的三元组中,不等的则分别储存在此新三元组中稀疏矩阵减法运算思路:将后一个矩阵的每一个非零元都乘以-1,再调用加法运算的函数稀疏矩阵乘法运算思路:逐个定位两个矩阵的非零元的位置,从第一个矩阵的第一行开始,再从第二个矩阵的第一列开始,找到非零元相乘相加,并利用累加器逐列累加稀疏矩阵求逆运算的思路:矩阵的逆等于矩阵的伴随矩阵除以矩阵行列式的值(1)定义全局变量#define MAX 100#define TRUE 1#define FAULT 0typedef int ElemType;(2)主函数模块说明主函数主要结构void main( ){ 初始化;Switch(){Case :接受命令;选择处理命令}不满足退出}void main( ){初始化;接受命令;选择处理命令}(3)其他模块说明(用文字描述,不要代码)int CreateSMatrix(TSMatrix *M){初始化;输入行数、列数、非零元个数for(){for()按行为主序输入每一个非零元赋值}返回结果}void PrintSMatrix(TSMatrix Q){两层for循环输出每一个非零元}void AddRLSMatrix(TSMatrix M,TSMatrix N,TSMatrix *Q){判断行数、列数是否对应相等,若均相等则相加并赋值否则依次判断行数、列数的大小并再次判断将值放在另一个数组里}Void JianRLSMatrix(TSMatrix M,TSMatrix N,TSMatrix *Q){两层for循环将第二个矩阵的每一个非零元变为他的负数再调用相加函数}void MultSMatrix(TSMatrix M,TSMatrix N,TSMatrix *Q){初始化判断第一个矩阵的行数时候等于第二个矩阵的列数然后逐个定位两个矩阵的非零元的位置,从第一个矩阵的第一行开始,再从第二个矩阵的第一列开始,找到非零元相乘相加,并利用累加器逐列累加}四、测试数据及程序运行情况三元组表实现加法运算三元组表实现乘法运算十字链表实现求逆运算五、实验过程中出现的问题及解决方案1)问题:运行过程中发现加法减法能正常运行,而乘法却在计算时出现问题。
数据结构课程设计报告--稀疏矩阵运算器
目录: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 乘法:⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡-700000001000000010034 X ⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎣⎡000001010024003 =⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡-000010008060 1.6 确定解决方案进入运算器界面后选择要实行的操作,按1实现矩阵相加,调用函数AddSMatrix ,若输入的两个矩阵行列数不相等,则提示输入错误,重新输入矩阵进行加法运算;按2实现矩阵相乘,若输入的第一矩阵的列数不等于第二个矩阵的行数,则提示输入错误,重新输入矩阵进行乘法运算;按3实现矩阵相减,若输入的两个矩阵行列数不相等,则提示输入错误,重新输入矩阵进行减法运算;按4退出程序以加法为例实现运算过程,如下:(稀疏矩阵的和为Q) 第一个稀疏矩阵M 的三元组为((1,1,10),(2,3,9),(3,1,-1)) 第二个稀疏矩阵N 的三元组为((2,3,-1),(3,1,1),(3,3,-3))M 的第一个三元组(1,1,10)与N 的第一个三元组(2,3,-1)比较,因行数1<2则Q 得到第一个三元组(1,1,10);M 的第二个三元组与N 的第一个三元组比较,因对应行列数相等则9+(-1)=8,次行列数就是Q 的行列数即得到Q 的第二个三元组为(2,3,8);M 第三个三元组(3,1,-1))与N 的第二个三元组进行比较,因对应行列数相等,且1+(-1)=0,则不进行相加;而此时只有 N 的第三个三元组(3,3,-3)符合条件,则Q 得到第三个三元组(3,3,-3);最终结果为 ((1,1,10),(2,3,8),(3,3,-3))1.7所有抽象数据类型的定义以顺序存储结构来表示三元组表,则可得到稀疏矩阵的一种压缩存储方式——三元组顺序表。
稀疏矩阵实验报告需求分析,1200字
稀疏矩阵实验报告需求分析需求分析报告:稀疏矩阵实验报告引言:稀疏矩阵是在矩阵中非零元素的个数远远小于零元素的个数的情况下,通过一种特殊的数据结构来存储和表示矩阵。
稀疏矩阵实验报告是对稀疏矩阵的存储和运算的实验过程的记录和总结,对于研究稀疏矩阵的性质和算法有着重要的意义。
本篇报告将对稀疏矩阵实验报告的需求进行详细分析,包括实验目的、实验方法、实验过程、实验结果和实验结论等方面。
一、实验目的(约200字):本实验旨在通过对稀疏矩阵的存储和运算的实验,掌握稀疏矩阵的特点、存储方式和运算方法,进一步了解并熟悉稀疏矩阵的相关算法和应用场景。
具体目的包括:掌握稀疏矩阵的存储结构和实现方法;了解常见的稀疏矩阵运算方法;分析稀疏矩阵算法在实际应用中的效果。
二、实验方法(约200字):本实验采用稀疏矩阵的压缩存储方法,包括三元组顺序表和十字链表两种方式。
在实验过程中,首先需要编写程序实现稀疏矩阵的创建和初始化,并通过输入或读取文件的方式导入测试数据。
其次,需要实现稀疏矩阵的基本运算,包括矩阵的加法、减法和乘法等。
最后,根据实际需求选择合适的测试数据,并对实验结果进行统计和分析。
三、实验过程(约300字):实验过程分为以下几个步骤:1. 稀疏矩阵的创建与初始化:根据实验需求,选择适当的稀疏矩阵存储方式,如三元组顺序表或十字链表,并编写相关程序进行创建与初始化。
2. 导入测试数据:通过输入或读取文件的方式,导入测试数据,包括稀疏矩阵的维度和非零元素的位置和值等信息。
3. 稀疏矩阵的基本运算:实现稀疏矩阵的加法、减法和乘法等基本运算,验证程序的正确性。
4. 测试与分析:选择合适的测试数据进行实验,记录实验结果,并对结果进行统计和分析,包括稀疏矩阵存储方式的对比和算法的效率比较等。
5. 编写实验报告:总结实验过程和结果,撰写实验报告,包括实验目的、实验方法、实验过程、实验结果和实验结论等内容。
四、实验结果与分析(约300字):通过本次实验,我们成功实现了稀疏矩阵的存储和运算。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(2)稀疏矩阵的相加:
void MatrixAdd(int A[max],int B[max],int C[max]),这个函数用 于实现数组A和数组B的相加,并将其相加的结果存入数组C。这个函数 讨论了数组在相加的过程中的几种情况: a、 A数组和B数组的行相等且列相等,两者直接相加后存入数组C中。 if(A[i]==B[j]) { if(A[i+1]==B[j+1]) { C[k]=A[i]; C[k+1]=A[i+1]; C[k+2]=A[i+2]+B[j+2]; k=k+3; i=i+3; j=j+3; } } b、A的列小于B的列,将A的三个元素直接存入C中
2、 系统分析
稀疏矩阵的保存:以一位数组顺序存放非零元素的行号、列号和数 值,行号为-1作为结束符。以三个一维数组存放一个系数矩阵中的一个 非零元素,为零额元素则不保存。用一个二重循环来实现判断每个系数
矩阵的非零元素是否为零,不为零,就将其行列下标和其值存入一维数 组中 稀疏矩阵的相加:用循环来判断存储A何B稀疏矩阵的两个一维数组 中的行列下标是否相等和其大小关系。若相等,则将两个一维数组的第 三个元素的值相加存入新的数组C里,行列下标不变的存入进去;若A的 列小于B的列,则将A的三个元素直接存入C中;若B的列小于A的列,则 将B的三个元素村日C中;若A的行小于B的行,则将A的三个元素存入C 中;若A的行大于B的行,则将B存入C中。
3、 概要设计
(1)主界面的设计:
定义两个矩阵a= 0 0 0 0 0 0 0 0 0 0 0 9 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 b= 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 1 0 0 4 0 0 0 0 0 0 0 8 0 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
for(i=0;i<m;i++)//输入稀疏矩阵F for(j=0;j<n;j++) scanf("%d",&F[i][j]); creatematrix(E,A);// E稀疏矩阵存储在数组A中 creatematrix(F,B);// F稀疏矩阵存储在数组B中 matrixadd(A,B,C);//相加 i=0;j=0;k=0; printf("A数组内容如下:\n"); while(A[i]!=-1) { printf("%5d,%5d,%5d\n",A[i],A[i+1],A[i+2]); i=i+3; } printf("B数组内容如下:\n"); while(B[j]!=-1) { printf("%5d,%5d,%5d\n",B[j],B[j+1],B[j+2]); j=j+3; } printf("C数组内容如下:\n"); while(C[k]!=-1) { printf("%5d,%5d,%5d\n",C[k],C[k+1],C[k+2]); k=k+3; }
目
一、概述 1 二、 系统分析 1 三、 概要设计 1 (1)主界面的设计: 2 (2)系数矩阵的存储 2 (3)具体实现流程图: 3 四、详细设计 4 (2)稀疏矩阵的相加: 5 五、 运行与测试 8 六、 总结与心得 8 参考文献 9 源代码 9
录
一、概述
稀疏矩阵的加法运算,既将稀疏矩阵A和B,他均为m行n列,分别以 数组的形式存放在A和B中,实现A+B=C,将所得的结果存放在C数组中。
5、 运行与测试
6、 总结与心得
在本次试验中,我掌握了稀疏矩阵的存储与转存的相关知识,了解 了两个稀疏矩阵的相加后的知识,并实现了稀疏矩阵的加法,明白在计 算机中我们对稀疏矩阵的处理,可以很大程度上的节约我们的存储空 间,是压缩原理的雏形。
参考文献
【1】《数据结构》严蔚敏.清华大学出版社. 【2】《数据结构课程设计》苏仕华.极械工业出版社. 【3】《程序设计》谭浩强 .清华大学出版社.
源代码
#include <stdio.h> #define m 6 #define n 8 #define max 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; } B[k]=-1; } //两个稀疏矩阵存储到两个数组中后相加存储到另一个数组中 void matrixadd(int A[max],int B[max],int C[max]) { int i=0,j=0,k=0; while (A[i]!=-1&&B[j]!=-1) { if (A[i]==B[j]) { k++; k++; B[k]=A[i][j];
if(A[i+1]<B[j+1]) { C[k]=A[i]; C[k+1]=A[i+1]; C[k+2]=A[i+2]; k=k+3; i=i+3; } c、B的列小于A的列,将B的三个元素直接存入C中 if(A[i+1]>B[j+1]) { C[k]=B[j]; C[k+1]=B[j+1]; C[k+2]=B[j+2]; k=k+3; j=j+3; } d、A的行小于B的行,将A的三个元素直接存入C中 if(A[i]<B[j]) { C[k]=A[i]; C[k+1]=A[i+1]; C[k+2]=A[i+2]; k=k+3; i=i+3; } e、B的行小于A的行,将B的三个元素直接存入C中 if(A[i]>B[j]) { C[k]=B[j]; C[k+1]=B[j+1]; C[k+2]=B[j+2]; k=k+3; j=j+3; } f、A结束B还有元素,将B的所有元素直接存入C中
if(A[i]==-1) while(B[j]!=-1) { C[k]=B[j]; C[k+1]=B[j+1]; C[k+2]=B[j+2]; k=k+3; j=j+3; } g、B结束A还有元素,将A的所有元素直接存入C中 if(B[i]==-1) while(A[i]!=-1) { C[k]=A[i]; C[k+1]=A[i+1]; C[k+2]=A[i+2]; k=k+3; i=i+3;} 最后定义C[k]=-1,结束算法。
if (A[i+1]==B[j+1]) { C[k]=A[i]; C[k+1]=A[i+1]; C[k+2]=A[i+2]+B[j+2]; k=k+3; i=i+3; j=j+3; } else if (A[i+1]<B[j+1]) { C[k]=A[i]; C[k+1]=A[i+1]; C[k+2]=A[i+2]; k=k+3; i=i+3; } else { C[k]=B[j]; C[k+1]=B[j+1]; C[k+2]=B[j+2]; k=k+3; j=j+3; }
} else if (A[i]<B[j]) { C[k]=A[i]; C[k+1]=A[i+1]; C[k+2]=A[i+2]+B[j+2]; k=k+3; i=i+3; } else { C[k]=B[j]; C[k+1]=B[j+1]; C[k+2]=B[j+2]; k=k+3; j=j+3; } } if (A[i]==-1) { while (B[j]!=-1) { C[k]=B[j]; C[k+1]=B[j+1]; C[k+2]=B[j+2];来自(3)具体实现流程图:
四、详细设计
(1)稀疏矩阵的转存:
void CreateMatrix(int A[m][n],int B[50]),这是一个将稀疏矩 阵转存的函数,类似于顺序存储三元组表。在这个方法中,只要用一个 二重循环来判断每个矩阵元素是否为零,若不为零,则将其行、列下标
及其值存入到一维数组B中对应的元素。在定义函数的过程中,我们需 要定义一个for循环,以完成行和列的转换及存储。在函数的末尾我们 定义一个B[K]=-1,用于结束非零元素的存储。 算法如下: 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; }
定义两个数组A和B,用于存储矩阵a和矩阵b的值;定义一个数组 C,用于存放数组A和数组B相加后的结果。
(2)系数矩阵的存储
用一维数组存放系数矩阵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[0]=0,B[1]=1,B[2]=2, B[3]=1,B[4]=3, B[5]=4, B[6]=2, B[7]=5, B[8]=6, B[9]=3, B[10]=4, B[11]=8, B[12]=4,B[13]=2,B[14]=1,B[15]=-1。