收藏 分销(赏)

稀疏矩阵的操作.doc

上传人:精*** 文档编号:2670641 上传时间:2024-06-04 格式:DOC 页数:20 大小:1.32MB 下载积分:10 金币
下载 相关 举报
稀疏矩阵的操作.doc_第1页
第1页 / 共20页
稀疏矩阵的操作.doc_第2页
第2页 / 共20页


点击查看更多>>
资源描述
(完整word)稀疏矩阵的操作 《稀疏矩阵的操作》 数据结构课程设计报告 专 业: 计算机科学与技术 班 级: 姓 名: 学 号: 指导教师: 完成日期:2013-1-9 目录 1课程设计题目与要求 3 1。1课程设计的目的: 3 1.2课程设计的题目: 3 1.3题目要求: 3 2 总体设计 4 2。1程序结构与整体示意图 4 2.2各子模块功能介绍 4 3详细设计 5 3.1引入常量 5 3。2存储结构 5 3。3程序流程图 6 4运行结果: 9 5课程设计总结 12 6参考书目 12 1课程设计题目与要求 1。1课程设计的目的: 1.掌握多维数组的逻辑结构和存储结构。 2.掌握稀疏矩阵的压缩存储及基本操作。 1。2课程设计的题目: 稀疏矩阵的操作 1。3题目要求: (1) 稀疏矩阵采用三元组表示,求两个具有相同行列数的稀疏矩阵A和B的相加矩阵C,并输出C。 (2) 求出A的转置矩阵D,输出D(用两种方法实现,原始算法和改进的算法). (3) 求两个稀疏矩阵A和B的相乘矩阵E,并输出E. 2 总体设计 2.1程序结构与整体示意图 函数的声明 void InitMatrix1(SMatrix& M);//顺序存储结构 对稀疏矩阵的初始化 void InitMatrix2(LMatrix& M);//链式存储结构 对稀疏矩阵的初始化 void InputMatrix1(SMatrix& M,int m,int n);//顺序存储结构 输入函数 void InputMatrix2(LMatrix& M,int m,int n);//链式存储结构 输入函数 void OutputMatrix1(SMatrix& M);//顺序存储结构 输出函数 void OutputMatrix2(LMatrix& M);//链式存储结构 输出函数 SMatrix Transpose(SMatrix& M);//顺序存储结构 普通转置 SMatrix FastTranspose(SMatrix& M);//顺序存储结构 快速转置 LMatrix Add(LMatrix& M1,LMatrix& M2);//链式存储结构 加法 void menu();// 菜单函数 2。2各子模块功能介绍 1. 稀疏矩阵的存储结构的建立 以结构体为基础建立存储结构,分为顺序存储和链式存储的方式.采用三元组法,对系数矩阵中非零的元素进行存储,存储行号、列号以及元素的值(value)并记录下行,列及非零元素个数. 2. 稀疏矩阵的初始化函数 将矩阵的行、列以及非零元素的个数初始化零,保持程序的稳定性。 3. 稀疏矩阵的录入函数 将非零的元素值的行、列以及值录入创建的矩阵中。 4. 稀疏矩阵的输出函数 将进行操作后的稀疏矩阵输出。 5. 稀疏矩阵的转置、快速转置以及加法函数函数 对稀疏矩阵进行一系列的操作。 6. 菜单函数 对操作进行说明。 3详细设计 3.1引入常量 #define MaxTerms 10 #define MaxRows 10 定义矩阵最大为10行10列 3.2存储结构 通过使用结构体来存储相关信息: struct Triple//定义三元组 顺序存储 { int row,col;//行号和列号 ElemType val;//元素值 }; struct SMatrix //定义稀疏矩阵的结构 顺序存储 { int m,n,t;//行,列及非零元素个数 Triple sm[MaxTerms+1]; }; struct TripleNode//三元组结点 链式存储结构 { int row,col; ElemType val; TripleNode* next; }; struct LMatrix//定义稀疏矩阵的结构 链式存储结构 { int m,n,t; TripleNode* vector[MaxRows+1]; }; 3.3程序流程图 输入函数 N Y 普通转置 N N Y Y 稀疏矩阵的加法 4运行结果: 主界面 顺序存储建立稀疏矩阵 稀疏矩阵的普通转置 稀疏矩阵的快速转置 三元组建立稀疏矩阵链式存储 稀疏矩阵的加法 5课程设计总结 在此课程设计中,实际对稀疏矩阵的操作。由于稀疏矩阵中存在大量的0值,对于程序来说,要把大量的0值存储起来再一个个的进行运算是非常浪费空间和时间的,为此,我们优化存储方式,通过三元组定义元素的行、列以及元素值来确定元素的基本属性。为0的则不进行定义。根据系数矩阵的定义,矩阵中有至少十分之九的元素值为0,通过三元组的存储, 我们至少节约了十分之九的存储的存储,在进行转置操作的操作中,可以近似的认为以直接访问的方式来访问元素的各个属性,即行、列以及元素的值.这样有大大减少了程序的运行时间. 在传统的普通二维矩阵中操作,必须通过双重甚至三重的for循环进行复制和操作,例如再赋值过程中,要通过双重的for进行赋值,时间复杂度为o(n^2),而在进行转置是,时间复杂度为 o(n^3),这种时间花费太大,而通过三元组,则大大减少时间。 数据结构是计算机专业必学的学习的课程,通过对数据结构的学习,我学到了对数据进行组织好操作的基本方法。一个好的程序员不仅仅熟悉各种语言,更重要的是学会各种算法并在存储的层次中对数据进行操作,通过好的结构,来缩短程序运行的时间复杂度,提高程序的运行效率。数据结构这门课程我感觉只是学了一点点而已,以后一定要加强对这门课程的深入学习,设计好的算法。 6参考书目 1. 谭浩强. C++程序设计。北京:清华大学出版社,2008. 2. 数据结构(C语言版) 人民邮电出版社,2011 源代码 #include 〈iostream〉 #define MaxTerms 10 #define MaxRows 10 using namespace std; typedef int ElemType; struct Triple//定义三元组 顺序存储 { int row,col;//行号和列号 ElemType val;//元素值 }; struct SMatrix //定义稀疏矩阵的结构 顺序存储 { int m,n,t;//行,列及非零元素个数 Triple sm[MaxTerms+1]; }; struct TripleNode//三元组结点 链式存储结构 { int row,col; ElemType val; TripleNode* next; }; struct LMatrix//定义稀疏矩阵的结构 链式存储结构 { int m,n,t; TripleNode* vector[MaxRows+1]; }; //以上是对顺序和链式存储结构定义 //函数的声明 void InitMatrix1(SMatrix& M);//顺序存储结构 对稀疏矩阵的初始化 void InitMatrix2(LMatrix& M);//链式存储结构 对稀疏矩阵的初始化 void InputMatrix1(SMatrix& M,int m,int n);//顺序存储结构 输入函数 void InputMatrix2(LMatrix& M,int m,int n);//链式存储结构 输入函数 void OutputMatrix1(SMatrix& M);//顺序存储结构 输出函数 void OutputMatrix2(LMatrix& M);//链式存储结构 输出函数 SMatrix Transpose(SMatrix& M);//顺序存储结构 普通转置 SMatrix FastTranspose(SMatrix& M);//顺序存储结构 快速转置 LMatrix Add(LMatrix& M1,LMatrix& M2);//链式存储结构 加法 void menu();// 菜单函数 int main() { SMatrix S1; //顺序结构声明S1 LMatrix L1,L2;//链式存储结构声明L1L2 LMatrix L;//用来存储L1 L2的和 int c,m=1; while(m==1) { menu(); cout<〈"请输入你需要的操作"〈<endl; cin〉〉c; switch(c) { case 1: InitMatrix1(S1); InputMatrix1(S1,10,10); OutputMatrix1(S1); break; case 2: OutputMatrix1(Transpose(S1)); break; case 3: OutputMatrix1(FastTranspose(S1)); break; case 4: InitMatrix2(L1); InputMatrix2(L1,10,10); OutputMatrix2(L1); break; case 5: InitMatrix2(L2); cout〈<”输入要相加的矩阵”〈<endl; InputMatrix2(L2,10,10); OutputMatrix2(L2); L=Add(L1,L2); OutputMatrix2(L); break; case 6: cout<〈”再见"<〈endl; exit(1); } } return 0; } void InitMatrix1(SMatrix& M)//顺序存储结构 对稀疏矩阵的初始化为0 { M.m=0; M.n=0; M。t=0; } void InitMatrix2(LMatrix& M)//链式存储结构 对稀疏矩阵的初始化为0 { int i; M。m=0;M。n=0;M。t=0; for(i=1;i<=MaxRows;i++) M。vector[i]=NULL; } void InputMatrix1(SMatrix& M,int m,int n)//顺序存储结构 输入函数 { M.m=m;M。n=n; int row,col,val;//row和col用来分别存储元素的行号和列号,val用来存储元素值,t为非零元素个数 int k=0; cout<〈"输入顺序三元组的行号列号以及该位置的元素值,以0 0 0为结束标志”〈〈endl; cin>>row>>col〉〉val; while(row!=0&&col!=0&&val!=0) { k++; M.sm[k].row=row; M。sm[k]。col=col; M.sm[k].val=val; cin>>row〉>col>>val; } M。t=k; } void InputMatrix2(LMatrix& M,int m,int n)//链式存储结构 输入函数 { M。m=m;M。n=n; int row,col,val; int k=0; cout〈〈”输入链式三元组中的行、列和对应值,以0 0 0为结束标志”〈<endl; cin〉〉row>〉col>>val; while(row!=0&&col!=0&&val!=0) { k++; TripleNode *p; TripleNode *newptr; newptr=new TripleNode;//建立新结点 newptr-〉row=row; newptr—〉col=col; newptr-〉val=val; newptr—>next=NULL; p=M.vector[row]; if(p==NULL) { M.vector[row]=newptr; } else { while(p—>next!=NULL) p=p—〉next; p->next=newptr; } cin〉>row〉〉col>〉val; } M。t=k; } void OutputMatrix1(SMatrix& M)//顺序存储结构 输出函数 { int i=1; cout〈<”矩阵为”〈〈endl; for(i=1;i〈=M.t;i++) { cout〈〈M。sm[i]。row〈〈" ”; cout〈〈M。sm[i].col〈〈” ”; cout<<M。sm[i]。val〈〈” "; cout<<endl; } } void OutputMatrix2(LMatrix& M)//链式存储结构 输出函数 { int i; TripleNode *p; cout<<"矩阵为"<<endl; for(i=1;i〈=M.m;i++) { for(p=M.vector[i];p!=NULL;p=p—〉next) { cout〈〈p—>row<〈" "〈〈p—>col<<" ”〈<p—>val; cout〈<endl; } } cout<<endl; } SMatrix Transpose(SMatrix& M)//普通转置 { SMatrix S; InitMatrix1(S); int m,n,t; m=M.m; n=M。n; t=M。t;//用m,n,t分别暂存M的行数、列数和非零元素的个数 S。m=n; S.n=m; S.t=t;//分别置S的行数域、列数域和非零元素的个数域为n,m和t if(t==0)//若是零矩阵则转换完毕返回 return S; int k=1;//用k指示S.sm数组中待存元素的下标 for(int col=1;col〈=n; col++) for(int i=1;i<=t;i++) if(M.sm[i]。col==col) { S.sm[k].row=col; S.sm[k]。col=M.sm[i].row; S.sm[k].val=M。sm[i]。val; k++; } return S;//返回转置矩阵S } SMatrix FastTranspose(SMatrix& M)//快速转置,不必考虑大量的0元素 { SMatrix S; InitMatrix1(S); int m,n,t; m=M。m; n=M。n; t=M.t;//用m,n,t分别暂存M的行数、列数和非零元素的个数 S.m=n; S.n=m; S。t=t;//分别置S的行数域、列数域和非零元素的个数域为n,m和t if(t==0)//若是零矩阵则转换完毕返回 return S; int* num=new int[n+1];//为num向量动态分配存储空间 int* pot=new int[n+1];//为pot向量动态分配存储空间 int col,i; for(col=1;col<=n;col++)//对num向量进行初始化,置每个分量为0 num[col]=0; for(i=1;i<=t;i++)//第1遍扫描数组M。sm,统计出每一列非零元素的个数 { int j=M。sm[i].col; num[j]++; } pot[1]=1; for(col=2;col<=n;col++)//计算每一列的第1个非零元素在S。sm中存储位置 pot[col]=pot[col—1]+num[col-1]; for(i=1;i<=t;i++)//对M.sm进行第2遍扫描,把每个元素行、列值互换写入到S.sm的确定位置 { int j=M.sm[i]。col; int k=pot[j]; S。sm[k]。row=j; S。sm[k]。col=M.sm[i]。row; S.sm[k]。val=M。sm[i].val; pot[j]++; } delete[] num;//删除动态分配的数组 delete[] pot; return S; } LMatrix Add(LMatrix& M1,LMatrix& M2)//矩阵加法 { LMatrix M;//暂存运算结果,以便返回 InitMatrix2(M); if((M1.n!=M2。n)||(M1。n!=M2.n)) { cout〈〈"两个矩阵规格不同”〈〈endl; exit(1); } M.m=M1。m; M.n=M1.n;//把其中一个加数矩阵的尺寸赋给结果矩阵 if((M1.t==0) && (M2.t==0)) return M; //进行两矩阵相加产生和矩阵 int k=0;//用k统计结果矩阵中结点的个数 for(int i=1;i<=M.m;i++)//循环的次数相当于矩阵的行数 { TripleNode *p1,*p2,*p; p1=M1.vector[i];//p1指向M1矩阵中第i行单链表的待相加的结点 p2=M2.vector[i];//p2指向M2矩阵中第i行单链表的待相加的结点 p=M。vector[i];//p指向M矩阵中第i行单链表的待相加的结点 while((p1!=NULL) && (p2!=NULL)) { TripleNode* newptr=new TripleNode; if(p1—〉col<p2->col)//赋值新结点,p1指针后移 { *newptr=*p1; p1=p1-〉next; } else if(p1->col〉p2-〉col)//赋值新结点,p2指针后移 { *newptr=*p2; p2=p2—〉next; } else//对具有相同列号的结点进行处理 if(p1—〉val+p2->val==0)//不建立新结点和链接 { p1=p1—>next; p2=p2—>next;//p1和p2指针后移 continue; } else //新结点值为两结点值之和,p1和p2指针后移 { *newptr=*p1; newptr->val+=p2—>val; p1=p1—>next; p2=p2—〉next; } newptr—>next=NULL;//将新结点的指针域置空 //把新结点链接到结果矩阵的第i行单链表的表尾 if(p==NULL) M.vector[i]=newptr; else p—>next=newptr; p=newptr; k++; } while(p1!=NULL) { TripleNode* newptr=new TripleNode; *newptr=*p1; newptr-〉next=NULL; if(p==NULL) M.vector[i]=newptr; else p-〉next=newptr; p=newptr; p1=p1-〉next; k++; } //若p2不为空,则把剩余结点复制链接到结果矩阵中 while(p2!=NULL) { TripleNode* newptr=new TripleNode; *newptr=*p2; newptr->next=NULL; if(p==NULL) M.vector[i]=newptr; else p—〉next=newptr; p=newptr; p2=p2—〉next; k++; } } M.t=k;//置和矩阵中结点数 cout<〈"相加后得矩阵”〈〈endl; return M;//返回和矩阵 } void menu()// 菜单函数 { cout〈〈" 稀疏矩阵运算 "〈〈endl; cout〈<” ***********************************”<〈endl; cout〈〈" ** 1。用三元组(顺序存储)建立矩阵 **”〈〈endl; cout〈〈" ** 2.矩阵普通转置 **”<<endl; cout<<” ** 3。矩阵快速转置 **”<<endl; // cout〈〈” ** 4。矩阵乘法 **”<〈endl; cout〈〈" ** 4。用三元组(链接存储)建立矩阵 **”<<endl; cout〈<” ** 5.矩阵加法 **"〈<endl; cout<〈" ** 6.退出 **”〈〈endl; cout<<” ***********************************”〈〈endl; }
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服