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

稀疏矩阵实验报告

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

1.1 设计题目

《稀疏矩阵应用》

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

1.2 功能需求分析

(1)设计函数建立稀疏矩阵,初始化值。
(2)设计函数输出稀疏矩阵的值。
(3)构造函数进行两个稀疏矩阵相加,输出最终的稀疏矩阵。
(4)构造函数进行两个稀疏矩阵的相乘,输出最终的稀疏矩阵。
(5)构造函数进行稀疏矩阵的转置,并输出结果。
(6)退出系统。

2. 概要设计

2.1 功能模块设计

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

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

struct OLNode
{
   
 int i,j;                                           
 ElemType e;                                      
 OLNode *right,*down;                              
};
typedef OLNode *OLink;
struct CrossList
{
   
 OLink *rhead,*chead;                               
 int mu,nu,tu;                                     
 };

3.2 主函数的算法设计

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

3.3. 代码实现

#include<stdio.h>
#include<stdlib.h>
#include<iostream.h>
#include<process.h>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int ElemType;

//------------------------------------------------------------------------------------------------

struct OLNode
{
   
 int i,j;                                           //非零元所在行、列
 ElemType e;                                        //非零元值
 OLNode *right,*down;                               //定义向右域和向下域
};

typedef OLNode *OLink;

struct CrossList
{
   
 OLink *rhead,*chead;                               //行、列表头的头节点
 int mu,nu,tu;                                      //矩阵的行、列和非零元个数
};


//------------------------------------------------------------------------------------------------


void Create(CrossList &M)                             //矩阵的创建
{
   
 int i,j,k,m,n,t;
 ElemType e;                                       //用于存放非零元值
 OLNode *p,*q;
 printf("Please input the rows 、columns and the values of the matrix:");
 scanf("%d%d%d",&m,&n,&t);                         //输入稀疏矩阵的行、列、非零元个数
 M.mu=m;                                           //把矩阵的总行数存入M.mu
 M.nu=n;                                           //把矩阵的总列数存入M.nu
 M.tu=t;                                           //把矩阵的非零元个数存入M.tu
 M.rhead=(OLink*)malloc((m+1)*sizeof(OLink));      //给对象M的行分配m+1个结点大小的空间用行头指针M.rhead指向第一个行结点
 if(!M.rhead)                                      //假如头结点分配成功
  exit(OVERFLOW);                               //退出程序,程序返回给操作系统的返回码是OVERFLOW
 M.chead=(OLink*)malloc((n+1)*sizeof(OLink));      //给对象M的列分配n+1个结点大小的空间用列头指针M.chead指向第一个列结点
 if(!M.chead)                                      //假如头结点分配成功
  exit(OVERFLOW);                               //退出程序,程序返回给操作系统的返回码是OVERFLOW
 for(k=1;k<=m;k++)                                 //初始化行头指针
  M.rhead[k]=NULL;
 for(k=1;k<=n;k++)                                 //初始化列头指针
  M.chead[k]=NULL;
 printf("Please input %d data:\n",M.tu);
 for(k=0;k<t;k++)
 {
   
  scanf("%d%d%d",&i,&j,&e);                     //输入t个非零元的信息
  if(i>m||j>n)                                  //假如输入的元素不在矩阵中
  {
   
            printf("Please input again:\n");
   exit(OVERFLOW);                           //退出程序,程序返回给操作系统的返回码是OVERFLOW
  }
  else                                          //假如输入的元素在矩阵中
  {
   
   p=(OLNode*)malloc(sizeof(OLNode));        //为p分配一个结点大小的空间
   if(!p)                                    //假如p不存在
    exit(OVERFLOW);                       //退出程序,程序返回给操作系统的返回码是OVERFLOW
   p->i=i;                                   //把非零元的行值赋给p->i
   p->j=j;                                   //把非零元的列值赋给p->j
   p->e=e;                                   //把非零元的值赋给p->e
   if(M.rhead[i]==NULL||M.rhead[i]->j>j)     //如果第i行的第一个结点为空或者要插入的非零元的列值小于第i行的第一个结点的列值
   {
   
    //p插入该行第一节点处
    p->right=M.rhead[i];                  //p的向右域指向没有插入前的第i行的第一个结点
    M.rhead[i]=p;                         //p指向没有插入前的第i行的第一个结点
   }
   else
   {
   
    //否则寻找行表插入位置
    for(q=M.rhead[i];q->right&&q->right->j<j;q=q->right);//这里的;表示对这个循环不执行任何操作
    p->right=q->right;                    //p的右向域指向q的右向域
    q->right=p;                           //p指向q的右向域
   }                                         //完成行插入
   if(M.chead[j]==NULL||M.chead[j]->i>i)     //假如第一个列结点为空或者第j列的第一个结点的行值大于要插入的行值
   {
   
    //p插入该列第一节点处
    p->down=M.chead[j]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值