# 数据结构课程设计大曝光(3)
**注:转发请注明出处,以免老师误以为本人抄袭……**
[TOC]
# 课程设计三 稀疏矩阵的转置、加法和乘法的实现
## 一、实习目的和任务:
### 【问题描述】
设计一个程序,演示用三元组和十字链表表示的稀疏矩阵的转置、加法和乘法的实现。
### 【基本要求】
- (1)演示稀疏矩阵A的三元组和十字链表的建立过程。
- (2)演示稀疏矩阵A的转置过程。
- (3)演示稀疏矩阵A和B 的相加过程。
- (4)演示稀疏矩阵A和B 的相乘过程。
## 二、概要设计:
**设计思路:演示三元组矩阵的的创建转置和十字链表的转置、加法和乘法**
### 1.三元组的顺序结构实现:
#### ADT TSMatrix;{
数据对象:D={aij|i=1,2,……,m;j=1,2,……n,ai,j∈ElemSet,m,n分别成为矩阵的行数和列数}
数据关系:R={Row,Col}
Row={<ai,j,ai,j+1>|1≤i≤m,1≤j≤n-1}
Col={<ai,j,ai+1,j>|1≤i≤m-1,1≤j≤n}
基本操作:
#### void initTS(TSMatrix &T)
操作结果:初始化三元组顺序表
#### Status CreateTS(TSMatrix &T)
初始条件:三元组顺序表T已存在
操作结果:由键盘输入创建三元组稀疏矩阵
#### void printTS(TSMatrix &t)
初始条件:三元组顺序表T已存在
操作结果:输出三元组数据
#### void printTM(TSMatrix &t)
初始条件:三元组顺序表T已存在
操作结果:输出三元组矩阵
#### Status TransposeSMatrix(TSMatrix &M,TSMatrix &T)
初始条件:三元组顺序表M,T已存在
操作结果:采用三元组表存储表示,求稀疏矩阵M的转置矩阵T
#### Status TransposeSMSelf(TSMatrix &M)
初始条件:三元组顺序表T已存在
操作结果:采用三元组表存储表示,将稀疏矩阵M自身转置
#### }ADT TSMatrix;
### 2、十字链表结构的实现:
#### ADT CrossList;{
数据对象:D={aij|i=1,2,……,m;j=1,2,……n,ai,j∈ElemSet,m,n分别成为矩阵的行数和列数}
数据关系:R={Row,Col}
Row={<ai,j,ai,j+1>|1≤i≤m,1≤j≤n-1}
Col={<ai,j,ai+1,j>|1≤i≤m-1,1≤j≤n}
基本操作:
#### void InitCrossList(CrossList &M)
操作结果:初始化十字链表M
#### void destroyOLNode(OLink o)
初始条件:十字链表行指针o指向的行存在
操作结果:利用递归销毁一行的节点
#### void destroyMatrix_OL(CrossList &c)
初始条件:十字链表c已存在
操作结果:销毁十字链表
#### Status initMatrixSize(CrossList &c,int mu,int nu)
初始条件:十字链表c已存在
操作结果:根据行数,列数初始化链表结构
#### Status InsertNode(CrossList &M,int i,int j,int e)
初始条件:十字链表M已存在
操作结果:在十字链表M中插入节点(任意位置)
#### Status CreateSMatrx_OL(CrossList &M)
初始条件:十字链表M已存在
操作结果:创建稀疏矩阵M,采用十字链表存储表示
#### Status insertLastNode(CrossList &c,int i,int j,int e)
初始条件:十字链表c已存在
操作结果:往行尾及列尾端插入节点(只有在确定插入节点在末尾才能用,为矩阵的转置,加法,乘法定制的函数)
#### Status TransposeMatrix(CrossList &m,CrossList &l)
初始条件:十字链表m,l已存在
操作结果:将矩阵m转置赋值给l
#### Status PlusMatrix(CrossList &a,CrossList &b,CrossList &c)
初始条件:十字链表a,b,c已存在
操作结果:将矩阵a与b的和赋值给c
#### Status MultMatrix(CrossList &a,CrossList &b,CrossList &c)
初始条件:十字链表a,b,c已存在
操作结果:将矩阵a与b的积赋值给c
#### Status printOLNOde(OLink p)
操作结果:输出十字链表节点,用作遍历函数
#### Status TraverseCL(CrossList &c,Status (* visit)(OLink p))
初始条件:十字链表c已存在
操作结果:十字链表的逐行遍历
#### Status printCL(CrossList &c)
初始条件:十字链表c已存在
操作结果:输出十字链表矩阵的三元组表示
#### Status TransNode(OLink p)
初始条件:十字链表节点p已存在
操作结果:将节点中的行列及指针进行交换
#### Status TransposeSelf(CrossList &m)
初始条件:十字链表m已存在
操作结果:将矩阵m自身转置
#### void printCLMatrix(CrossList &c)
初始条件:十字链表c已存在
操作结果:输出十字链表矩阵的矩阵表示
#### }ADT CrossList;
### 3、用户交互的实现:
- char *oprcmd="CcMmTtSs'";-------------------------定义用户可以使用的操作
- char *opecmd="LlMmTtNnUu"----------------------定义用户可以使用的操作数
- char *spccmd="+*HhEeXx\033"----------------------定义用户可以使用的命令
- instr(char cmd,char *precmd)---------------判断c是否在str中,用于命令判断
- int isCmd(char *cmd) -----------------------判断是否为可识别的命令
- void Pause() -----------------------------------暂停并按任意键继续
- void Help() ------------------------------------输出命令帮助
- void openScreen()-----------------------------输出开始界面
- void inCMD(char *cmd)---------------------命令输入
- void Goodbye(CrossList &l,CrossList &m,CrossList &n)----------------退出界面并完成销毁工作
- void CMDtran(char* c,CrossList &l,CrossList &m,CrossList &n,TSMatrix &t,TSMatrix &u)------------解释命令并执行
- void CMDTrans(int &step,int &n,char *s,SqStack &a,SqStack &b,SqStack &c)----------------------------将字符串命令解释执行并输出执行后的汉诺塔状态
### 4、其他
- void swap(int &a,int &b)---------------交换a,b两元素的值
- int getint(int &n)-------------------------从键盘得到一个整数值
## 三、程序代码:
```C
/*-------------------------------------------------
三元组表示的稀疏矩阵的转置、加法和乘法的实现。
【问题描述】
设计一个程序,演示用三元组和十字链表表示的稀疏矩阵的转置、加法和乘法的实现。
【基本要求】
(1)演示稀疏矩阵A的三元组和十字链表的建立过程。
(2)演示稀疏矩阵A的转置过程。
(3)演示稀疏矩阵A和B 的相加过程。
(4)演示稀疏矩阵A和B 的相乘过程。
-----------------------------------------------*/
#include "stdio.h"
#include "stdlib.h"
#include "conio.h"
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
//Status 是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef int ElemType;//元素类型
void swap(int &a,int &b)
{//交换a,b两元素的值
int temp;
temp=a;
a=b;
b=temp;
}//swap
int getint(int &n)
{//输入整数值
n=0;
char c;
do{
do{
c=getch();
}while((c>'9'||c<'0')&&c!='\015'&&c!='\b'&&c!=' '||(c=='\015'&&n==0)||(c==' '&&n==0));
if(c>='0'&&c<='9'){
n=n*10+(c-'0');
if(!(n==0&&c=='0'))putch(c);
}else if(c=='\b'&&n!=0){
printf("\b \b");
n=n/10;
}else if(c=='\015'||c==' ')
putch('\012');
}while(c!='\015'&&c!=' ');
return n;
}//getint
//--------------------------稀疏矩阵的三元组顺序表存储表示----------------------
#define MAXSIZE 500 //假设矩阵非零元个数的最大值为500
#define MAXRC 1000//假设矩阵最多为1000行
typedef struct {
int i,j;//该非零元的行下标和列下标
ElemType e;
}Triple;
typedef struct{
Triple data[MAXSIZE+1];//非零元三元组表,data[0]未用
int mu,nu,tu;//矩阵的行数、列数和非零元个数
}TSMatrix;
Status CreateTS(TSMatrix &T){//创建三元组稀疏矩阵
int k,mu,nu,tu;
printf("输入行数,列数和非零元个数\n");
// scanf("%d%d%d",&mu,&nu,&tu);
do{
printf("请输入行数:");getint(mu);
printf("请输入列数:");getint(nu);
printf("请输入非零元个数:");getint(tu);
}while(mu*nu<tu);
if(tu>MAXSIZE)return OVERFLOW;
T.tu=tu;T.mu=mu;T.nu=nu;
printf("请按照顺序输入其行号、列号及非零元(不按顺序或输入重复元素会出现意想不到的错误)\n");
for(k=1;k<=tu;k++){
// scanf("%d%d%d",&i,&j,&e);
printf("---------第%d个非零元---------\n",k);
do{printf("请输入行号:");getint(T.data[k].i);}while(T.data[k].i>mu);
do{printf("请输入列号:");getint(T.data[k].j);}while(T.data[k].j>nu);
printf("请输入非零元数据:");getint(T.data[k].e);
}//for
return OK;
}//CreateTS
void initTS(TSMatrix &T)
{//初始化三元组链表
T.mu=0;T.nu=0;T.tu=0;
}//initTS
void printTS(TSMatrix &t){//输出三元组数据
int i;
printf("三元组矩阵有%d行%d列%d个非零元\n",t.mu,t.nu,t.tu);
printf("以下为其数据元素:\n");
for(i=1;i<=t.tu;i++)
printf("\t%d\t%d\t%d\t\n",t.data[i].i,t.data[i].j,t.data[i].e);
}//printTS
void printTM(TSMatrix &t){//输出三元组矩阵
int x,y,z=1;
for(x=1;x<=t.mu;x++){//行循环
for(y=1;y<=t.nu;y++){//列循环
if(t.data[z].i==x&&t.data[z].j==y){//当前元素为非零元
printf("\t%d",t.data[z].e);z++;
}//if
else//当前元素为零元
printf("\t0");
}//for
printf("\n");//换行,准备输出下一行
}//for
}//printTM
Status TransposeSMatrix(TSMatrix &M,TSMatrix &T){
//采用三元组表存储表示,求稀疏矩阵M的转置矩阵T
int q,col,p;//非零元,行,列 循环变量
T.mu=M.mu;T.nu=M.mu;T.tu=M.tu;
if(T.tu){
q=1;
for(col=1;col<=M.nu;++col)
for(p=1;p<=M.tu;++p)
if(M.data[p].j==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;
++q;
}//if
}//if
return OK;
}//TransposeSMatrix
Status TransposeSMSelf(TSMatrix &M){
//采用三元组表存储表示,将稀疏矩阵M自身转置
int q=1,md,p;
if(M.tu){//交换行列号
for(p=1;p<=M.tu;++p)
swap(M.data[p].i,M.data[p].j);
for(p=1;p<M.tu;++p){//进行排序
md=p;
for(q=p;q<=M.tu;++q){//选择排序,比较过程
if(M.data[md].i>M.data[q].i||(M.data[md].i==M.data[q].i&&M.data[md].j>M.data[q].j))
md=q;
}
if(md!=p){//选择排序,交换过程
swap(M.data[p].i,M.data[md].i);
swap(M.data[p].j,M.data[md].j);
swap(M.data[p].e,M.data[md].e);
}//if
}
}//if
return OK;
}//TransposeSMatrix
//----------------稀疏矩阵的十字链表 存储结构 定义--------------------------
typedef struct OLNode{//十字链表的三元组结构体
int i,j;//该非零元的行和列下标
ElemType e;//数据元素
struct OLNode *right,*down;//该非零元所在行表和列表的后继链域
}OLNode,* OLink;
typedef struct {
OLink *rhead,*chead;//行和列链表头指针向量基址由CreateSMatrix分配
int mu,nu,tu;//系数矩阵的行数列数和非零元个数
}CrossList;
//----------------稀疏矩阵的十字链表 函数实现--------------------------
void InitCrossList(CrossList &M)
{//初始化十字链表
M.mu=0;M.nu=0;M.tu=0;
M.chead=NULL;M.rhead=NULL;
}//InitCrossList
void destroyOLNode(OLink o)
{//利用递归销毁一行的节点
if(o->right)destroyOLNode(o->right);
free(o);
}//destroyOLNode
void destroyMatrix_OL(CrossList &c)
{//销毁十字链表
int i;
for(i=1;i<=c.nu;i++)
{
if(c.rhead[i])
destroyOLNode(c.rhead[i]);
}//for
free(c.chead);
free(c.rhead);
c.mu=0;c.nu=0;c.tu=0;
}//destroyMatrix_OL
Status initMatrixSize(CrossList &c,int mu,int nu)
{//根据行数,列数初始化链表结构
int i;
if(c.tu||c.nu)destroyMatrix_OL(c);
c.mu=mu;c.nu=nu;
//给行列头指针分配空间
if(!(c.rhead=(OLink *)malloc((mu+1)*sizeof(OLink))))exit(OVERFLOW);
if(!(c.chead=(OLink *)malloc((nu+1)*sizeof(OLink))))exit(OVERFLOW);
//初始化行列头指针向量,各行列链表为空链表
for(i=0;i<=mu;i++)
c.rhead[i]=NULL;
for(i=0;i<=nu;i++)
c.chead[i]=NULL;
return OK;
}
Status InsertNode(CrossList &M,int i,int j,int e)
{//插入节点(任意位置)
OLink p,q;
if(!(p=(OLNode *)malloc(sizeof(OLNode))))exit(OVERFLOW);
p->i=i;p->j=j;p->e=e;p->down=NULL;p->right=NULL;//生成节点
if(M.rhead[i]==NULL||M.rhead[i]->j>j){
p->right=M.rhead[i];M.rhead[i]=p;
}//if
else if(M.rhead[i]==NULL||M.rhead[i]->j==j){
free(p);return ERROR;
}//else if
else {//巡查在行表中的插入位置
for(q=M.rhead[i];(q->right)&&q->right->j<j;q=q->right);
if(q->right!=NULL&&q->right->j==j){
free(p);return ERROR;
}//if
p->right=q->right;q->right=p;
}//else if
//完成行插入
if(M.chead[j]==NULL||M.chead[j]->i>i){p->down=M.chead[j];M.chead[j]=p;}//if
else{//巡查在列表中的插入位置
for(q=M.chead[j];(q->down)&&q->down->i<i;q=q->down);
p->down=q->down;q->down=p;
}//else if
//完成列插入
return OK;
}//InsertNOde
Status CreateSMatrx_OL(CrossList &M){
//创建稀疏矩阵M,采用十字链表存储表示
int m,n,t,i,j,k;
ElemType e;
printf("输入行数,列数和非零元个数\n");
// scanf("%d%d%d",&m,&n,&t);
//输入M的行数,列数和非零元个数
do{
printf("请输入行数:");getint(m);
printf("请输入列数:");getint(n);
printf("请输入非零元个数:");getint(t);
}while(m*n<t);
// if(m*n<t)return ERROR;//行列乘积不能大于非零元个数
initMatrixSize(M,m,n);//根据行数,列数初始化链表结构
M.tu=t; //初始化非零元个数
printf("输入其行号、列号及非零元(可以不按顺序)\n");
for(k=1;k<=M.tu;k++){//按任意顺序输入非零元
// scanf("%d%d%d",&i,&j,&e);
printf("----------第%d个非零元----------\n",k);
do{printf("请输入行号:");getint(i);}while(i>m);
do{printf("请输入列号:");getint(j);}while(j>n);
printf("请输入非零元数据:");getint(e);
if(!InsertNode(M,i,j,e)){k--;};
}//for
return OK;
}//CreateSMatrx_OL
Status insertLastNode(CrossList &c,int i,int j,int e)
{//往行尾及列尾端插入节点(只有在确定插入节点在末尾才能用,为矩阵的转置,加法,乘法定制的函数)
OLink r,*s;
if(!(r=(OLNode *)malloc(sizeof(OLNode))))exit(OVERFLOW);
r->i=i;r->j=j;r->e=e;r->right=NULL;r->down=NULL;//给节点赋值
for(s=&(c.rhead[i]);(*s);s=&((*s)->right));(*s)=r;//巡查在行表中的插入位置并插入
for(s=&(c.chead[j]);(*s);s=&((*s)->down));(*s)=r;////巡查在列表中的插入位置并插入
return OK;
}
Status TransposeMatrix(CrossList &m,CrossList &l)
{//将矩阵m转置赋值给l
OLink p;//循环,临时指针
int i;//循环变量
initMatrixSize(l,m.nu,m.mu);//根据行数,列数初始化链表结构
l.tu=m.tu;//初始化非零元个数
for(i=1;i<=m.nu;i++)
{//逐行计算
for(p=m.rhead[i];p;p=p->right){
insertLastNode(l,p->j,p->i,p->e);//往行尾及列尾端插入节点
}//for
}//for
return OK;
}//TransposeMatrix
Status PlusMatrix(CrossList &a,CrossList &b,CrossList &c)
{//将矩阵a与b的和赋值给c
OLink p,q;//循环,临时指针
int i,j,e,k=0;//循环变量 ,临时数据 ,累计非零元个数
if(a.mu!=b.mu||a.nu!=b.nu)return ERROR;
initMatrixSize(c,a.mu,a.nu);//根据行数,列数初始化链表结构
for(i=1;i<=a.mu;i++){//逐行计算
p=a.rhead[i];q=b.rhead[i];
while(p||q) {//对此行中每个非零元遍历
if((p&&q)&&(p->j==q->j&&p->e+q->e==0))
{//不需要插入节点时的情况
p=p->right;q=q->right;
}//if
else{//需要插入节点时的情况
if(q==NULL){//b中此行已无非零元
j=p->j; e=p->e; p=p->right;
}//else if
else if(p==NULL){//a中此行已无非零元
j=q->j;e=q->e;q=q->right;
}//else if
else if(p->j<q->j){
j=p->j;e=p->e;p=p->right;
}//else if
else if(p->j>q->j){
j=q->j;e=q->e;q=q->right;
}//else if
else if(p->j==q->j){
j=q->j;e=p->e+q->e;p=p->right;q=q->right;
}//else if
k++;
insertLastNode(c,i,j,e);//往行尾及列尾端插入节点
}//else
}//while
}//for
c.tu=k;
return OK;
}//PlusMatrix
Status MultMatrix(CrossList &a,CrossList &b,CrossList &c)
{//将矩阵a与b的积赋值给c
OLink p,q;//循环,临时指针
int i,j,e,k;//循环变量 ,临时数据,非零元个数累加器
if(a.mu!=b.nu||a.nu!=b.mu)return ERROR;
initMatrixSize(c,a.mu,b.nu);//根据行数,列数初始化链表结构
for(i=1;i<=a.mu;i++){//a的行
for(j=1;j<=b.nu;j++){//b的列
p=a.rhead[i];q=b.chead[j];e=0;//循环初值
while(p&&q)
{
if(p->j<q->i)p=p->right;
else if(p->j>q->i)q=q->down;
else if(p->j==q->i){//对应元素
e+=(p->e)*(q->e);//相乘并累加
p=p->right;q=q->down;
}//else if
}//while
if(e!=0){//当元素不为0时插入节点
k++;
insertLastNode(c,i,j,e);//往行尾及列尾端插入节点
}//if
}//for
}//for
c.tu=k;
return OK;
}//MultMatrix
Status printOLNOde(OLink p)
{//输出十字链表节点,用作遍历函数
printf("\t%d\t%d\t%d\t\n",p->i,p->j,p->e);
return OK;
}//printOLNOde
Status TraverseCL(CrossList &c,Status (* visit)(OLink p))
{//十字链表的逐行遍历
int i;
OLink p;
for(i=1;i<=c.mu;i++)
{//逐行计算
for(p=c.rhead[i];p;p=p->right)//对此行中每个非零元遍历
if(!visit(p))return ERROR;
}//for
return OK;
}//TraverseCL
Status printCL(CrossList &c)
{//输出十字链表矩阵的三元组表示
printf("十字链表矩阵有%d行%d列%d个非零元\n",c.mu,c.nu,c.tu);
printf("以下为其数据元素:\n");
printf("\t\t\t\t\n");
TraverseCL(c,printOLNOde);
return OK;
}//printCL
Status TransNode(OLink p)
{//将节点中的行列及指针进行交换
swap(p->i,p->j);
swap((int &)p->right,(int &)p->down);
return OK;
}//TransNode
Status TransposeSelf(CrossList &m)
{//将矩阵m自身转置
swap((int &)m.chead,(int &)m.rhead);//先交换行列表头
TraverseCL(m,TransNode);//然后用交换节点行列及指针的函数遍历十字链表
return OK;
}//TransposeMatrix
void printCLMatrix(CrossList &c)
{//输出十字链表矩阵的矩阵表示
int i,j;
OLink p;
for(i=1;i<=c.nu;i++)
{//行
p=c.rhead[i];
for(j=1;j<=c.mu;j++)
{//列
if(p&&j==p->j)
{//此元素为非零元
printf("\t%d",p->e);
p=p->right;
}//if
else
{//此元素为零元
printf("\t0");
}//else
}//for(j)
printf("\n");
}//for(i)
}//printCLMatrix
//------------------------------命令及界面 函数 定义 开始-----------------------
void Pause()
{//按任意键继续
printf("\n按任意键继续……\n");
getch();
}//Pause
void Goodbye(CrossList &l,CrossList &m,CrossList &n)
{//显示结束画面,并结束程序
//用完销毁
destroyMatrix_OL(l);destroyMatrix_OL(m);destroyMatrix_OL(n);
system("cls");//清屏
printf("\n\n\n\n\t\t\tGoodbye\n\n");
printf("\t\t\t\t******CopyLeft#WrittenByhuaying1988.com******\n\n");
Pause();//按任意键继续
exit(0);
}//Goodbye
void Help()
{//命令帮助
printf("命令说明:\n\
cx------------------建立/重建矩阵x并输出\n\
mx------------------以矩阵形式输出矩阵x\n\
tx------------------以三元组形式输出矩阵x\n\
sx------------------将x自身转置并输出x\n\
'x------------------计算并输出x的转置(三元组存入u中,十字链表存入n中)\n\
+ ------------------计算n=l+m并输出\n\
* ------------------计算n=l*m并输出\n\
H-------------------(help)命令帮助\n\
E/X-----------------(exit)退出\n\
不区分大小写,不允许有多余字符,其中的'x'处只可以是t,m,l,n,u\n\
其中t为三元组表示的稀疏矩阵,m,l为十字链表表示的稀疏矩阵\n");
}//Help
void OpenScreen()
{//开始画面
system("color f0");
system("title 十字链表矩阵运算演示程序 WrittenBy huaying1988.com");
printf("\n\n\n\t\t\t十字链表矩阵运算演示程序\n");
printf("\t\t\t**学院 **07-*\n");
printf("\t\t\thuaying1988.com 学号:***********\n");
printf("\n\t说明:\n\
演示用三元组和十字链表表示的稀疏矩阵的转置、加法和乘法的实现\n\n");
printf("\t\t\t\t******CopyLeft#WrittenByhuaying1988.com******\n\n");
Pause();
system("cls");
Help();
}//OpenScreen
void CMDtran(char* c,CrossList &l,CrossList &m,CrossList &n,TSMatrix &t,TSMatrix &u)
{//解释命令并执行
void *ope=NULL,*fun=NULL;
int flag=0;//标志操作三元组(1)或十字链表(2)
switch(c[1])
{//操作数
case 't':
case 'T':
ope=(void *)&t;
flag=1;
break;
case 'l':
case 'L':
ope=(void *)&l;
flag=2;
break;
case 'm':
case 'M':
ope=(void *)&m;
flag=2;
break;
case 'N':
case 'n':
ope=(void *)&n;
flag=2;
break;
case 'U':
case 'u':
ope=(void *)&u;
flag=1;
break;
default:flag=0;
}//switch c[1]
switch(c[0])
{//操作符
case 'H'://pass through
case 'h'://命令帮助
Help();
return;
case 27://pass through
case 'x':
case 'X':
case 'e'://pass through
case 'E'://退出
Goodbye(l,m,n);//三元组不用销毁
//exit(0);
break;
case '+':
PlusMatrix(l,m,n);
printf("m与l的和:\n");
printCLMatrix(n);
break;
case '*':
MultMatrix(l,m,n);
printf("m与l的积:\n");
printCLMatrix(n);
break;
case 'c':
case 'C':
if(flag==2){
if((*(CrossList *)ope).tu>0){
printf("矩阵%c已存在,是否重建?(y/*)\n",c[1]);
if(getch()=='y'){
printf("建立十字链表矩阵%c:\n",c[1]);
CreateSMatrx_OL(*(CrossList *)ope);
printf("矩阵%c已建立:\n",c[1]);
printCLMatrix(*(CrossList *)ope);
}else printf("用户撤销重建……\n");
}//if
else{
printf("建立十字链表矩阵%c:\n",c[1]);
CreateSMatrx_OL(*(CrossList *)ope);
printf("矩阵%c已建立:\n",c[1]);
printCLMatrix(*(CrossList *)ope);
}//else
}//if
else if(flag==1){
if((*(CrossList *)ope).tu>0){
printf("矩阵%c已存在,是否重建?(y/*)\n",c[1]);
if(getch()=='y'){
printf("建立三元组矩阵t:\n");
CreateTS(*(TSMatrix *)ope);
printf("矩阵t已建立:\n");
printTM(*(TSMatrix *)ope);
}else printf("用户撤销重建……\n");
}//if
else{
printf("建立三元组矩阵t:\n");
CreateTS(*(TSMatrix *)ope);
printf("矩阵t已建立:\n");
printTM(*(TSMatrix *)ope);
}//else
}//else if
break;
case 'm':
case 'M':
if(flag)printf("矩阵%c:\n",c[1]);
if(flag==2)printCLMatrix(*(CrossList *)ope);
else if(flag==1)printTM(*(TSMatrix *)ope);
break;
case 't':
case 'T':
if(flag)printf("矩阵%c:\n",c[1]);
if(flag==2)printCL(*(CrossList *)ope);
else if(flag==1)printTS(*(TSMatrix *)ope);
break;
case 's':
case 'S':
if(flag)printf("转置后矩阵%c变为:\n",c[1]);
if(flag==2){
TransposeSelf(*(CrossList *)ope);
printCLMatrix(*(CrossList *)ope);
}//if
else if(flag==1){
TransposeSMSelf(*(TSMatrix *)ope);
printTM(*(TSMatrix *)ope);
}//else if
break;
case '\047'://'
if(flag)printf("矩阵%c的转置为:\n",c[1]);
if(flag==2){
TransposeMatrix(*(CrossList *)ope,n);
printCLMatrix(n);
}//if
else if(flag==1){
TransposeSMatrix(*(TSMatrix *)ope,u);
printTM(u);
}//else if
break;
default://其他输入
printf("不能识别的命令\n");
}//switch c[0];
}//CMDtran
void inCMD(char *cmd)
{//命令输入函数
printf("\nh-help,e-exit|请输入命令:\n");
scanf("%s",cmd);
putch('\n');
}//inCMD
int instr(char cmd,char *precmd)
{//判断是否为命令
int i;
for(i=0;precmd[i]!='\0';i++)
{
if(precmd[i]==cmd)return 1;
}//for
return 0;
}//instr
char *oprcmd="CcMmTtSs'";//操作
char *opecmd="LlMmTtNnUu";//操作数
char *spccmd="+*HhEeXx\033";//命令
int isCmd(char * cmd)
{//判断是否为命令
if((instr(cmd[0],spccmd)&&cmd[1]==0)||(instr(cmd[0],oprcmd)&&instr(cmd[1],opecmd)&&cmd[2]==0))
return 1;
printf("无法识别的命令\n");
return 0;
}//isCmd
//-----------------------------命令及界面 函数 定义 结束-----------------------
int main()
{
CrossList l,m,n;TSMatrix t,u;//声明
char cmd[100]={0};//用来存储命令
InitCrossList(l);InitCrossList(m);//初始化
InitCrossList(n);initTS(t);initTS(u);
OpenScreen();//开始画面
while(1){
do{//如果输入不是命令则重复输入
inCMD(cmd);
}while(!isCmd(cmd));
CMDtran(cmd,l,m,n,t,u);
}
return 0;
}
```
## 四、测试数据及结果分析:
**运行界面:**
![运行界面](matrix.jpg "运行界面")
开始画面以后,显示命令说明和命令提示符,输入“ct”,回车,按提示依次输入:
```
建立三元组矩阵t:
请输入行数,列数和非零元个数
请输入行数:4
请输入列数:4
请输入非零元个数:5
输入其行号、列号及非零元
---------第1个非零元---------
请输入行号:1
请输入列号:1
请输入非零元数据:6
---------第2个非零元---------
请输入行号:1
请输入列号:3
请输入非零元数据:9
---------第3个非零元---------
请输入行号:2
请输入列号:2
请输入非零元数据:5
---------第4个非零元---------
请输入行号:3
请输入列号:4
请输入非零元数据:12
---------第5个非零元---------
请输入行号:4
请输入列号:2
请输入非零元数据:16
矩阵t已建立:
6 0 9 0
0 5 0 0
0 0 0 12
0 16 0 0
输入”st”,将其转置并显示:
转置后矩阵t变为:
6 0 0 0
0 5 0 16
9 0 0 0
0 0 12 0
同理,输入”cl”,回车,依次输入以下数据:
5 5 7 1 1 11 1 3 13 2 2 14 2 5 16 3 4 17 4 1 18 5 5 15
可建立如下矩阵:
矩阵l已建立:
11 0 13 0 0
0 14 0 0 16
0 0 0 17 0
18 0 0 0 0
0 0 0 0 15
再输入“cm”回车,依次输入如下数据:
5 5 8 1 2 21 1 4 22 2 1 24 2 3 23 3 5 26 4 2 28 4 3 29 5 5 25
建立如下矩阵:
矩阵m已建立:
0 21 0 22 0
24 0 23 0 0
0 0 0 0 26
0 28 29 0 0
0 0 0 0 25
输入“'l”,回车,”’m”,回车,分别查看l,m的转置:
矩阵l的转置为:
11 0 0 18 0
0 14 0 0 0
13 0 0 0 0
0 0 17 0 0
0 16 0 0 15
矩阵m的转置为:
0 24 0 0 0
21 0 0 28 0
0 23 0 29 0
22 0 0 0 0
0 0 26 0 25
输入“+”查看l+m的和
m与l的和:
11 21 13 22 0
24 14 23 0 16
0 0 0 17 26
18 28 29 0 0
0 0 0 0 40
输入“*”查看l+m的积
m与l的积:
0 231 0 242 338
336 0 322 0 400
0 476 493 0 0
0 378 0 396 0
0 0 0 0 375
输入“sm”,将m转置
转置后矩阵m变为:
0 24 0 0 0
21 0 0 28 0
0 23 0 29 0
22 0 0 0 0
0 0 26 0 25
再次输入“*”和“+”查看它们的和与积
m与l的和:
11 24 13 0 0
21 14 0 28 16
0 23 0 46 0
40 0 0 0 0
0 0 26 0 40
m与l的积:
0 563 0 377 0
294 0 416 392 400
374 0 0 0 0
0 432 0 0 0
0 0 390 0 375
```
经检验,运行结果完全正确。
**注:转发请注明出处,以免老师误以为本人抄袭……**