数据结构与算法分析课程设计:稀疏矩阵的应用

1.设计题目与功能需求分析

 

1.1设计题目

稀疏矩阵应用

要求:实现三元组,十字链表下的稀疏矩阵的加、转、乘的实现。

1.2功能需求分析

1)设计函数建立稀疏矩阵,初始化值。

2)设计函数输出稀疏矩阵的值。

3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。

4)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。

5)构造函数进行稀疏矩阵的转置,并输出结果。

6)退出系统。

 

2.概要设计

 

2.1功能模块设计

从系统的功能需求分析,得到系统主要包括以下几大功能模块,分别是建立主函数、创建三元组表、创建矩阵、矩阵相加减、矩阵转置等。其功能模块图如下图所示:

   

 

 

                      图系统功能模块图

 

2.2模块简介

 

依据程序的功能模块划分,各模块定义如下:

 

1)定义稀疏矩阵框架

 

模块名:struct OLNode

 

模块描述:通过此模块可以定义矩阵内部元素类型及指针类型

 

2)创建稀疏矩阵信息

 

模块名:void Create(CrossList &M)

 

模块描述:根据文字提示,输入稀疏矩阵的行、列、非零元的全部信息。

 

(3)输出符合上述步骤中信息的稀疏矩阵

 

模块名:void Print(CrossList M)

 

模块描述:以矩阵的显示方式显示稀疏矩阵。

 

4)进行稀疏矩阵的加运算

 

模块名:void Add(CrossList M,CrossList N,CrossList &Q)

 

模块描述:根据文字提示,如果两个矩阵不是同类型的,程序返回给操作系统的返回码是OVERFLOW;如果两个矩阵是同类型的,相加程序运行

 

5)进行稀疏矩阵的转置运算

 

模块名:void Trans(CrossList M,CrossList &N)

 

模块描述:定义结点,扫描矩阵,进行矩阵的转置运算

 

6)进行稀疏矩阵的乘运算

 

模块名:void Mult(CrossList M,CrossList N,CrossList &Q)

 

模块描述:判断矩阵M的总列数是否等于矩阵N的总行数若是,程序运行,否则,提示出错

 

 

3.详细设计

 

 

3.1数据结构

 

本程序采用结构体数组,对稀疏矩阵中非零元素的行、列、值以及指针。

 

 1 struct OLNode
 2 {
 3  int i,j;                                           
 4  ElemType e;                                      
 5  OLNode *right,*down;                              
 6 };
 7 typedef OLNode *OLink;
 8 struct CrossList
 9 {
10  OLink *rhead,*chead;                               
11  int mu,nu,tu;                                     
12  };

 

3.2主函数的算法设计

首先显示菜单及运用菜单选择实现相应功能,输入稀疏矩阵行、列以及非零元,系统菜单调用采用while循环,在循环体中用switch语句调用各个功能函数,最后退出程序。

主函数的程序流程图如下图所示:

             

                    图函数流程图

 

3.3程序代码实现

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<iostream.h>
  4 #include<process.h>
  5 #define OK 1
  6 #define ERROR 0
  7 #define OVERFLOW -2
  8 typedef int ElemType;
  9 
 10 //------------------------------------------------------------------------------------------------
 11 
 12 struct OLNode
 13 {
 14  int i,j;                                           //非零元所在行、列
 15  ElemType e;                                        //非零元值
 16  OLNode *right,*down;                               //定义向右域和向下域
 17 };
 18 
 19 typedef OLNode *OLink;
 20 
 21 struct CrossList
 22 {
 23  OLink *rhead,*chead;                               //行、列表头的头节点
 24  int mu,nu,tu;                                      //矩阵的行、列和非零元个数
 25 };
 26 
 27 
 28 //------------------------------------------------------------------------------------------------
 29 
 30 
 31 void Create(CrossList &M)                             //矩阵的创建
 32 {
 33  int i,j,k,m,n,t;
 34  ElemType e;                                       //用于存放非零元值
 35  OLNode *p,*q;
 36  printf("Please input the rows 、columns and the values of the matrix:");
 37  scanf("%d%d%d",&m,&n,&t);                         //输入稀疏矩阵的行、列、非零元个数
 38  M.mu=m;                                           //把矩阵的总行数存入M.mu
 39  M.nu=n;                                           //把矩阵的总列数存入M.nu
 40  M.tu=t;                                           //把矩阵的非零元个数存入M.tu
 41  M.rhead=(OLink*)malloc((m+1)*sizeof(OLink));      //给对象M的行分配m+1个结点大小的空间用行头指针M.rhead指向第一个行结点
 42  if(!M.rhead)                                      //假如头结点分配成功
 43   exit(OVERFLOW);                               //退出程序,程序返回给操作系统的返回码是OVERFLOW
 44  M.chead=(OLink*)malloc((n+1)*sizeof(OLink));      //给对象M的列分配n+1个结点大小的空间用列头指针M.chead指向第一个列结点
 45  if(!M.chead)                                      //假如头结点分配成功
 46   exit(OVERFLOW);                               //退出程序,程序返回给操作系统的返回码是OVERFLOW
 47  for(k=1;k<=m;k++)                                 //初始化行头指针
 48   M.rhead[k]=NULL;
 49  for(k=1;k<=n;k++)                                 //初始化列头指针
 50   M.chead[k]=NULL;
 51  printf("Please input %d data:\n",M.tu);
 52  for(k=0;k<t;k++)
 53  {
 54   scanf("%d%d%d",&i,&j,&e);                     //输入t个非零元的信息
 55   if(i>m||j>n)                                  //假如输入的元素不在矩阵中
 56   {
 57             printf("Please input again:\n");
 58    exit(OVERFLOW);                           //退出程序,程序返回给操作系统的返回码是OVERFLOW
 59   }
 60   else                                          //假如输入的元素在矩阵中
 61   {
 62    p=(OLNode*)malloc(sizeof(OLNode));        //为p分配一个结点大小的空间
 63    if(!p)                                    //假如p不存在
 64     exit(OVERFLOW);                       //退出程序,程序返回给操作系统的返回码是OVERFLOW
 65    p->i=i;                                   //把非零元的行值赋给p->i
 66    p->j=j;                                   //把非零元的列值赋给p->j
 67    p->e=e;                                   //把非零元的值赋给p->e
 68    if(M.rhead[i]==NULL||M.rhead[i]->j>j)     //如果第i行的第一个结点为空或者要插入的非零元的列值小于第i行的第一个结点的列值
 69    {
 70     //p插入该行第一节点处
 71     p->right=M.rhead[i];                  //p的向右域指向没有插入前的第i行的第一个结点
 72     M.rhead[i]=p;                         //p指向没有插入前的第i行的第一个结点
 73    }
 74    else
 75    {
 76     //否则寻找行表插入位置
 77     for(q=M.rhead[i];q->right&&q->right->j<j;q=q->right);//这里的;表示对这个循环不执行任何操作
 78     p->right=q->right;                    //p的右向域指向q的右向域
 79     q->right=p;                           //p指向q的右向域
 80    }                                         //完成行插入
 81    if(M.chead[j]==NULL||M.chead[j]->i>i)     //假如第一个列结点为空或者第j列的第一个结点的行值大于要插入的行值
 82    {
 83     //p插入该列第一节点处
 84     p->down=M.chead[j];                   //p的向下域指向没有插入前的第j列的第一个结点
 85     M.chead[j]=p;                         //p指向没有插入前的第j列的第一个结点
 86    }                                         //完成列插入
 87    else
 88    {
 89     //否则寻找列表插入位置
 90     for(q=M.chead[j];q->down&&q->down->i<i;q=q->down);//这里的;表示对这个循环不执行任何操作
 91     p->down=q->down;                      //p的向下域指向q的向下域
 92     q->down=p;                            //p指向q的向下域
 93    }                                         //完成列插入
 94   }
 95  }
 96 }
 97 
 98 
 99 //------------------------------------------------------------------------------------------------
100 
101 void Print(CrossList M)                               //矩阵的输出
102 {
103  int i,j,k;
104  OLink p;                                          //定义结点指针p
105  int array[100][100];                              //定义二元数组array[100][100]
106  for(i=1;i<=M.mu;i++)                              //行循环
107  {
108   for(j=1;j<=M.nu;j++)                          //列循环
109   {
110    array[i][j]=0;                            //初始化数组所需部分
111   }
112  }
113  for(k=1;k<=M.nu;k++)                              //将所有非零元的值存入对应的数组中
114  {
115   p=M.rhead[k];                                 //p指向第k行的第一个结点
116   while(p)
117   {
118    //将第k行的非零元存入数组中
119    array[p->i][p->j]=p->e;                   //将这个结点的非零元存入数组中
120    p=p->right;                               //p指向下一个向右域
121   }
122  }
123  for(i=1;i<=M.mu;i++)                              //行循环
124  {
125   for(j=1;j<=M.nu;j++)                          //列循环
126   {
127    if(j==M.nu)
128     cout<<array[i][j]<<endl;              //如果是行的最后一个结点则换行
129    else
130     cout<<array[i][j]<<" ";               //以矩阵的显示方式显示稀疏矩阵
131   }
132  }
133 }
134 
135 
136 //------------------------------------------------------------------------------------------------
137 
138 
139 void Add(CrossList M,CrossList N,CrossList &Q)  //矩阵M和矩阵N相加并存入矩阵Q
140 {
141  int i,k;
142  OLink p,pq,pm,pn;
143  OLink *col;
144  if(M.mu!=N.mu||M.nu!=N.nu)                 //如果两个矩阵不是同类型的
145  {
146   printf("The two matrixes is not of the same type!/n");
147   exit(OVERFLOW);                        //退出程序,程序返回给操作系统的返回码是OVERFLOW
148  }
149  //对Q进行初始化
150  Q.mu=M.mu;                                 //矩阵Q的总行数和矩阵M的总数相同
151  Q.nu=M.nu;                                 //矩阵Q的总列数和矩阵M的总数相同
152  Q.tu=0;                                    //将矩阵Q的非零元个数初始化为零
153  Q.rhead=(OLink*)malloc((Q.mu+1)*sizeof(OLink));  //给对象Q的行分配Q.mu+1个结点大小的空间用行头指针Q.rhead指向第一个行结点
154  if(!Q.rhead)                               //如果行分配空间成功
155   exit(OVERFLOW);                        //退出程序,程序返回给操作系统的返回码是OVERFLOW
156  Q.chead=(OLink*)malloc((Q.nu+1)*sizeof(OLink));  //给对象Q的列分配Q.nu+1个结点大小的空间用列头指针Q.chead指向第一个列结点
157  if(!Q.chead)                               //如果列分配空间成功
158   exit(OVERFLOW);                        //退出程序,程序返回给操作系统的返回码是OVERFLOW
159  for(k=1;k<=Q.mu;k++)                       //初始化行
160   Q.rhead[k]=NULL;
161  for(k=1;k<=Q.nu;k++)                       //初始化列
162   Q.chead[k]=NULL;
163  col=(OLink*)malloc((Q.nu+1)*sizeof(OLink));//生成指向列的起始节点的指针
164  if(!col)                                   //如果分配空间成功
165   exit(OVERFLOW);                        //退出程序,程序返回给操作系统的返回码是OVERFLOW
166  for(k=1;k<=Q.nu;k++)                       //赋初始值
167   col[k]=NULL;
168  for(i=1;i<=M.mu;i++)                       //按行序相加
169  {
170   pm=M.rhead[i];                         //pm指向矩阵M的第i行的头结点
171   pn=N.rhead[i];                         //pn指向矩阵N的第i行的头结点
172   while(pm&&pn)                          //如果pm和pn都存在
173   {
174    if(pm->j<pn->j)                    //矩阵M当前结点的列小于矩阵N当前结点的列
175    {
176     //生成Q的结点
177     p=(OLink)malloc(sizeof(OLNode));  //给p分配一个结点大小的空间
178     if(!p)                         //如果分配空间不成功
179      exit(OVERFLOW);            //退出程序,程序返回给操作系统的返回码是OVERFLOW
180     Q.tu++;                        //矩阵Q的非零元个数加1
181     p->i=i;                        //把非零元的行赋给p->i
182     p->j=pm->j;                    //把矩阵M中当前结点列的值赋给p->j
183     p->e=pm->e;                    //把矩阵M中当前结点的元素值赋给p->e
184     p->right=NULL;                 //p的向右域为空
185     pm=pm->right;                  //pm右移
186    }
187    else if(pm->j>pn->j)               //矩阵M当前结点的列大于矩阵N当前结点的列
188    {
189     p=(OLink)malloc(sizeof(OLNode));//给p分配一个结点大小的空间
190     if(!p)                          //如果分配空间不成功
191      exit(OVERFLOW);             //退出程序,程序返回给操作系统的返回码是OVERFLOW
192     Q.tu++;                         //矩阵Q的非零元个数加1
193     p->i=i;                         //把矩阵当前非零元的行赋给p->i
194     p->j=pn->j;                     //把矩阵N中当前结点列的值赋给p->j
195     p->e=pn->e;                     //把矩阵N中当前结点的元素值赋给p->e
196     p->right=NULL;                  //p的向右域为空
197     pn=pn->right;                   //pn右移
198    }
199    else if(pm->e+pn->e)                //M,N当前结点的列相同并且两元素之和非零
200    {
201     p=(OLink)malloc(sizeof(OLNode));//给p分配一个结点大小的空间
202     if(!p)                          //如果分配空间不成功
203      exit(OVERFLOW);             //退出程序,程序返回给操作系统的返回码是OVERFLOW
204     Q.tu++;                         //矩阵Q的非零元个数加1
205     p->i=i;                         //把矩阵当前非零元的行赋给p->i
206     p->j=pn->j;                     //把矩阵当前非零元的列赋给p->j
207     p->e=pm->e+pn->e;               //把矩阵M当前非零元的值和矩阵N当前非零元的值相加赋给p->e
208     p->right=NULL;                  //p的向右域为空
209     pm=pm->right;                   //pm右移
210     pn=pn->right;                   //pn右移
211    }
212    else                                //两元素相加为零
213    {
214     pm=pm->right;                   //pm右移
215     pn=pn->right;                   //pn右移
216     continue;                       //不执行下面的程序,回到循环
217    }
218    if(Q.rhead[i]==NULL)                //如果当前行的头结点为空
219     Q.rhead[i]=pq=p;                //把p结点中的数据赋给pq结点和结点Q.rhead[i],pq结点用来保存当前的位置
220    else                                //如果当前的头结点不为空
221    {
222     pq->right=p;                    //pq的向右域指向p
223     pq=pq->right;                   //pq指向pq的向右域
224    }                                   //完成行插入
225    if(Q.chead[p->j]==NULL)             //如果当前列的头结点为空
226     Q.chead[p->j]=col[p->j]=p;      //把p结点中的数据赋给结点col[p->j]和当前列的头结点Q.chead[p->j]
227    else
228    {
229     //如果当前结点不为空,则插入p结点
230     col[p->j]->down=p;
231     col[p->j]=col[p->j]->down;
232    }
233   }
234   while(pm)    //如果矩阵M中的结点还没有插完,将矩阵M该行的剩余元素插入矩阵Q
235   {
236    p=(OLink)malloc(sizeof(OLNode));    //给结点p分配空间
237    if(!p)
238     exit(OVERFLOW);
239    Q.tu++;                             //矩阵非零元个数加1
240    p->i=i;                             //把当前结点的行、列、和值插入p中
241    p->j=pm->j;
242    p->e=pm->e;
243    p->right=NULL;                      //p的向右域为空
244    pm=pm->right;                       //pm右移
245             if(Q.rhead[i]==NULL)                //如果当前行头结点为空,直接插入p结点
246     Q.rhead[i]=pq=p;
247    else                                //如果当前行头结点不为空,插入p结点
248    {
249     pq->right=p;
250     pq=pq->right;
251    }
252    if(Q.chead[p->j]==NULL)             //如果当前列头结点为空,直接插入p结点
253     Q.chead[p->j]=col[p->j]=p;    
254    else                                //如果当前列头结点不为空,插入p结点
255    {
256     col[p->j]->down=p;
257     col[p->j]=col[p->j]->down;
258    }
259   }
260   while(pn)                               //如果矩阵N中的结点还没有插完,将矩阵N该行的剩余元素插入矩阵Q
261   {
262    p=(OLink)malloc(sizeof(OLNode));    //给结点p分配空间
263    if(!p)
264     exit(OVERFLOW);
265    Q.tu++;                             //矩阵非零元个数加1
266    p->i=i;                             //把当前结点的行、列、和值插入p中
267    p->j=pn->j;
268    p->e=pn->e;
269    p->right=NULL;                      //p的向右域为空
270    pn=pn->right;                       //pn右移
271             if(Q.rhead[i]==NULL)                //如果当前行头结点为空,直接插入p结点
272     Q.rhead[i]=pq=p;
273    else                                //如果当前行头结点不为空,插入p结点
274    {
275     pq->right=p;
276     pq=pq->right;
277    }
278    if(Q.chead[p->j]==NULL)             //如果当前列头结点为空,直接插入p结点
279     Q.chead[p->j]=col[p->j]=p;
280    else                                //如果当前列头结点不为空,插入p结点
281    {
282     col[p->j]->down=p;
283     col[p->j]=col[p->j]->down;
284    }
285   }
286     }
287  for(k=1;k<=Q.nu;k++)                    //使得每一列的最后一个结点的向下域为空
288   if(col[k])
289    col[k]->down=NULL;
290   free(col);                              //释放col的空间
291 }
292 
293 //------------------------------------------------------------------------------------------------
294 
295 
296 void Trans(CrossList M,CrossList &N)            //将矩阵M转置到矩阵N中
297 {
298  OLink p,q,s;                                //定义三个结点p、q、s
299  int i,j;
300  N.mu=M.mu;                                  //将矩阵M中的行、列和非零元值赋给矩阵N
301  N.nu=M.nu;
302  N.tu=M.tu;
303  if(N.rhead==NULL)                           //如果矩阵N的行为空
304   N.rhead=(OLink *)malloc((N.mu+1)*sizeof(OLink));//给矩阵N的行分配N.mu+1个结点大小的空间
305  for(i=1;i<=N.mu;i++)                        //对矩阵N的行进行初始化
306   N.rhead[i]=NULL;
307  if(N.chead==NULL)                           //如果矩阵N的列为空
308   N.chead=(OLink *)malloc((N.nu+1)*sizeof(OLink));//给矩阵N的列分配N.nu+1个结点大小的空间
309  for(j=1;j<=N.nu;j++)                        //对矩阵N的列进行初始化
310   N.chead[j]=NULL;
311  for(i=1;i<=M.mu;i++)                       
312  {
313   for(s=M.rhead[i];s!=NULL;s=s->right)    //对矩阵M的第i行进行扫描
314   {
315    p=(OLink)malloc(sizeof(OLink));     //给p分配一个结点大小的空间
316    p->i=s->j;                          //将扫描到的结点中的数据进行转置后存到结点p中
317    p->j=s->i;
318    p->e=s->e;
319    if(N.rhead[p->i]==NULL || N.rhead[p->i]->j>p->j)//如果p结点所在行的头结点为空或者头结点的列大于p结点的列值将p结点插入到第一个结点
320    {
321     p->right=N.rhead[p->i];
322     N.rhead[p->i]=p;
323    }
324    else
325    {
326     for(q=N.rhead[p->i];q->right && q->right->j<p->j;q=q->right);//扫描直到扫描到的列值大于要插入的结点的列值,则把p结点插入到这个结点的后面
327     p->right=q->right;
328     q->right=p;
329    }
330    if(N.chead[p->j]==NULL || N.chead[p->j]->i > p->i)//如果p结点所在列的头结点为空或者头结点的行值大于p结点的行值将p结点插入到第一个结点
331    {
332     p->down=N.chead[p->j];
333     N.chead[p->j]=p;
334    }
335    else
336    {
337     for(q=N.chead[p->j];q->down && q->down->i < p->i; q=q->down);//扫描当前列,直到扫描到的结点的行值大于要插入的结点的行值,则把p结点插入到这个结点的后面
338     p->down=q->down;
339     q->down=p;
340    }
341   }
342  }
343 }
344 
345 
346 //------------------------------------------------------------------------------------------------
347 
348  
349 
350 void Mult(CrossList M,CrossList N,CrossList &Q)//把矩阵M和矩阵N相乘并存入到矩阵Q中
351 {
352  int i,j,e;
353  OLink q,p0,q0,q1,q2;
354  if(M.nu!=N.mu)        //如果矩阵M的总列数不等于矩阵N的总行数,则不能矩阵相乘              
355  {
356   printf("The matrix what you input is error!/n");
357   exit(OVERFLOW);
358  }
359  else                                   //如果矩阵M的总列数等于矩阵N的总行数
360  {
361   Q.mu=M.mu;                             //把矩阵M的总行数赋给Q.mu
362   Q.nu=N.nu;                             //把矩阵N的总列数赋给Q.nu
363   Q.tu=0;                                //矩阵Q的非零元个数置为零
364   Q.rhead=(OLink*)malloc((Q.mu+1)*sizeof(OLink));  //给矩阵Q的行头指针分配Q.mu+1个结点大小的空间
365   if(!Q.rhead)
366    exit(OVERFLOW);
367   Q.chead=(OLink*)malloc((Q.nu+1)*sizeof(OLink));  //给矩阵Q的列头指针分配Q.nu+1个结点大小的空间
368   if(!Q.chead)
369    exit(OVERFLOW);
370   for(i=1;i<=Q.mu;i++)                   //初始化行
371    Q.rhead[i]=NULL;
372   for(i=1;i<=Q.nu;i++)                   //初始化列
373    Q.chead[i]=NULL;
374   for(i=1;i<=Q.mu;i++)
375    for(j=1;j<=Q.nu;j++)
376    {
377     p0=M.rhead[i];                  //p0指向矩阵M第i行头结点
378     q0=N.chead[j];                  //q0指向矩阵N第j列头结点
379     e=0;                            //定义变量e的值为0
380     while(p0&&q0)                   //当矩阵M和矩阵N的当前结点都存在时
381     {
382      if(q0->i<p0->j)             //如果q0当前所在行小于p0当前所在列,q0下移
383       q0=q0->down;
384      else if(q0->i>p0->j)        //如果q0当前所在行大于p0当前所在列,p0右移
385       p0=p0->right;
386      else
387      {
388       e=e+p0->e*q0->e;        //乘积累加
389       q0=q0->down;            //行列后移
390       p0=p0->right;
391      }
392     }
393     if(e)                           //e不为零则插入Q
394     {
395      Q.tu++;                     //矩阵Q的非零元个数加1 
396      q=(OLink)malloc(sizeof(OLNode));  //给q分配空间
397      if(!q)
398       exit(OVERFLOW);
399      q->i=i;                     //把当前元素的行、列和值赋给结点q
400      q->j=j;
401      q->e=e;
402      q->right=NULL;              //结点q的向右域为空
403      q->down=NULL;               //结点q的向下域为空
404      if(!Q.rhead[i])         //如果Q矩阵当前行的头结点为空,将结点q中的数据赋给Q.rhead和结点q1:用来存储当前位置
405       Q.rhead[i]=q1=q;
406      else                        //否则将q中的数据赋给q1的向右域,并将q1右移
407       q1=q1->right=q;
408      if(!Q.chead[j])             //如果Q矩阵当前列的头结点为空,将结点q中的数据赋给Q.chead
409       Q.chead[j]=q;
410      else
411      {
412       q2=Q.chead[j];          //将当前列的头结点数据赋给q2
413       while(q2->down)         //如果q2的向下域存在
414        q2=q2->down;        //q2下移
415       q2->down=q;             //把当前要插入的结点q插入到结点q2的后面
416      }
417     }
418    }
419  }
420 }
421 
422 //------------------------------------------------------------------------------------------------
423 
424 
425 void main()
426 {
427  CrossList A,B,C;                               //声明三个矩阵
428  int Select;                                    //用来表示所要选择的序号
429  cout<<"*****************************************************************************"<<endl;
430  cout<<"******************************"<<"请选择你需要的操作"<<"*****************************"<<endl;
431  printf("/t/t/t<1>.Press 1 to add the array;\n");
432  printf("/t/t/t<2>.Press 2 to trans the array;\n");
433  printf("/t/t/t<3>.Press 3 to multiply the array;\n");
434  cout<<"*****************************************************************************"<<endl;
435  while(printf("Please input the serial number:"),cin>>Select)
436  {
437   switch(Select)
438   {
439   case 1 : //稀疏矩阵相加
440    {
441     Create(A);                          
442     Create(B);                          
443     cout<<"The array A is:"<<endl;
444     Print(A);                           
445     cout<<"To add array B:"<<endl;
446     Print(B);                           
447     Add(A,B,C);                         //把矩阵A和矩阵B相加存入到矩阵C中
448     cout<<"The result is:"<<endl;
449     Print(C);                           //输出矩阵C
450     break;
451    }
452   case 2 ://稀疏矩阵转置
453    {
454     Create(A);                          
455     Create(B);                          
456     cout<<"The array A is:"<<endl;
457     Print(A);                           
458     cout<<"Trans to B:"<<endl;
459     Trans(A,B);                         //将矩阵A转置到矩阵B中
460     cout<<"The result is:"<<endl;
461     Print(B);                           //输出矩阵B
462     break;
463    }
464   case 3 : //稀疏矩阵相乘
465    {  
466     Create(A);                          
467     Create(B);                           
468     cout<<"The array A is:"<<endl;
469     Print(A);                           
470     cout<<"To multiply array B:"<<endl;
471     Print(B);                            
472     Mult(A,B,C);                   //把矩阵A和矩阵B相乘所得的矩阵存入矩阵C中
473     cout<<"The result is:"<<endl;
474     Print(C);                            //输出矩阵C
475     break;
476    }
477   }
478  }
479 }

 

4.运行结果与调试分析

 

 

4.1系统主界面

        

                        图3  系统主界面

 

4.2输入稀疏矩阵相关信息

 

输入要进行的操作,之后输入稀疏矩阵行、列、非零元素个数。根据提示再输入非零元素所在行、列以及值。

   

 

 

                      图4  构造稀疏矩阵

 

若在输入非零元素行、列时,所输入的位置并不在矩阵中则程序报错,需要重新进行输入。

  

 

 

            图5 非零元素不在所输入的矩阵中时,程序报错提示

 

4.3输出稀疏矩阵加运算结果

 

输入稀疏矩阵,进行矩阵的加法运算

  

 

 

                图6 稀疏矩阵的加运算运行结果

 

若输入的两个矩阵行、列数不同,在输出两个输入的矩阵后,程序报错并提示两个矩阵类型不同。

  

 

 

              图7 进行加运算时,两个矩阵类型不同时程序报错提示

 

4.4输出稀疏矩阵转置运算结果

   

 

 

                图8 稀疏矩阵的转置运算运行结果

 

4.5输出稀疏矩阵乘运算结果

     

 

 

                   图9 稀疏矩阵的乘运算运行结果

 

 

5.总结体会

 

通过此次课程设计,我以实际程序的运行,熟悉了用三元组、十字链表下稀疏矩阵的加、转、乘运算。在实验中,我们要培养的是自己的独立思考能力和独立解决问题的能力。通过此次试验我也认识到了数据结构与算法分析这门课程的重要性,以及C语言功能的强大。C语言可以让计算机进行各种需要的操作,当然进行这些操作的前提是自己的技术水平要过关。

 

纸上得来终觉浅,得知此事要躬行。数据结构与算法分析这门课程理论和实践同等重要,在此次的课程设计实验,程序本身还有很多不足的地方,我自己的问题还有很多。也正因如此,我的前进的空间还很大,希望在之后的计算机相关课程中学到更多知识,提高自己的动手实践能力。

 

 

 

6.参考文献

 

[1]严蔚敏,吴伟民.数据结构(C语言版)[M].北京:清华大学出版社

 

[2]苏小红,孙志岗等.C语言大学实用教程[M].北京:电子工业出版社

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2021-01-26 17:46  Lucilla1027  阅读(1044)  评论(0)    收藏  举报