广东工业大学数据结构实验报告
题目: 稀疏矩阵
1.题目: 抽象数据类型稀疏矩阵 ADT 定义如下:
ADT SparseMatrix{
数据对象:D={aij| i=1,2,...,m; j=1,2,...,n;
aij∈ElemSet, m 和n分别称为矩阵的行数和列数}
数据关系:R={Row,Col}
Row={
Col={
基本操作:
Status CreateSMatrix(TSMatrix &M)
操作结果:创建稀疏矩阵M
Status DestroySMatrix(TSMatrix &M)
初始条件:稀疏矩阵M已经存在
操作结果:销毁矩阵M
void PrintSMatrix(TSMatrix M)
初始条件:稀疏矩阵M已经存在
操作结果:打印矩阵M
Status CopySMatrix(TSMatrix M, TSMatrix &T)
初始条件:稀疏矩阵M已经存在
操作结果:复制矩阵M到T
Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)
初始条件:稀疏数组M、N的行数和列数对应相等
操作结果:求矩阵的和Q=M+N
Status SubSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)
初始条件:稀疏数组M、N的行数和列数对应相等
操作结果:求矩阵的差Q=M-N
Status TransposeSMatrix(TSMatrix M, TSMatrix & T)
初始条件:稀疏数组M已经存在
操作结果:求矩阵M的转置T
Status MultSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)
初始条件:稀疏数组M的列数等于N的行数
操作结果:求矩阵的积Q=M*N
StatusFindElem(TSMatrix M, int row, int col, ElemType &e)
初始条件:稀疏数组M存在
操作结果:查找第row行,第col列元素,若不为0则用e返回其值
StatusInsertElem(TSMatrix &M, int row, int col, ElemType e)
初始条件:稀疏数组M存在
操作结果:在第row行,第col列位置插入元素e
StatusDeleteElem(TSMatrix &M, int row, int col, ElemType &e)
初始条件:稀疏数组M存在
操作结果:删除第row行,第col列元素
StatusIsEmptyMatrix(TSMatrix M)
操作结果:判断是否为空矩阵
}ADT SparseMatrix
2.存储结构定义
稀疏矩阵的三元组顺序表存储表示
#define MAXSIZE 50
typedef struct {
int i, j;
ElemType e;
}Triple;
typedef struct {
Tripledata[MAXSIZE+1];
intmu, nu, tu;
}TSMatrix;
3. 算法设计
#include
#include
#define TRUE 1;
#define FALSE 0;
#define OK 1
#define ERROR 0;
typedef intStatus;
typedef intElemType;
/* 稀疏矩阵的三元组顺序表存储表示 */
#define MAXSIZE 50
typedef struct {
int i, j;
ElemType e;
}Triple;
typedef struct {
Triple data[MAXSIZE+1]; //这里可用数组实现也可用指针实现
int mu, nu, tu;
}TSMatrix;
//对三元组表示的稀疏矩阵进行排序
//需要排序是因为创建三元组时可以任意不按顺序输入
voidOrder(TSMatrix &M){
int a, b;
Triple t;
for(a=1; a for(b=a+1; b if(M.data[a].i > M.data[b].i){ //如果前面一个行号比后面一 //个行号大,就交换 t = M.data[a]; M.data[a] = M.data[b]; M.data[b] = t; } if(M.data[a].i ==M.data[b].i){ //行号相等,列号大的在后面 if(M.data[a].j >M.data[b].j){ t = M.data[a]; M.data[a] = M.data[b]; M.data[b] = t; } } } } } //销毁稀疏矩阵M StatusDestroySMatrix(TSMatrix &M){ //要想销毁一个三元组表示的 //矩阵就必须销毁四部分 int num = M.tu; //M.mu,M.nu,M.tu和M.data[] M.mu = 0; M.nu = 0; M.tu = 0; for(int k=1; k<=num; k++){ //因为用数组实现,又数组为静 // 态分配,故销毁数组只能置其内容为0 M.data[k].i = 0; // 而不能释放其空间 M.data[k].j = 0; M.data[k].e = 0; } return OK; } //创建稀疏矩阵M StatusCreateSMatrix(TSMatrix &M){ if(M.tu != 0) //M如果非空 DestroySMatrix(M); int m, n, t, i, j, e; int flag = 0; //flag用来标志输入是否重复 printf("请输入矩阵的行数、列数和非零元个数(格式为:X,X,X)\n"); while(1){ scanf("%d,%d,%d",&m,&n,&t); if(t<=0 || m<=0 || n<=0){ //输入的行列数要为整数 printf("对不起,您输入有误!请重新输入!\n"); printf("请输入矩阵的行数、列数和非零元个数(格式为:X,X,X)\n"); }else if(t > m*n){ //非零元个数不能大于矩阵最大个数 printf("对不起,您输入的非零元个数不合理!请重新输入!\n"); printf("请输入矩阵的行数、列数和非零元个数(格式为:X,X,X)\n"); }else //输入正确 break; } M.mu = m; M.nu = n; M.tu = t; printf("请输入你想创建的稀疏矩阵:(格式为:X,X,X)\n"); for(int k=1; k<=M.tu; k++){ scanf("%d,%d,%d",&i,&j,&e); if(i > M.mu){ printf("输入有误,行号过大,请重新输入!\n"); k--; }else if(i <= 0){ printf("输入有误,行号必须为正数,请重新输入!\n"); k--; }else if(j <= 0){ printf("输入有误,列号必须为正数,请重新输入!\n"); k--; }else if(j > M.nu){ printf("输入有误,列号过大,请重新输入!\n"); k--; }else if(e == 0){ printf("输入有误,值不能为零,请重新输入!\n"); k--; }else { for(int t=1; t<=k; t++){ if(i==M.data[t].i &&j==M.data[t].j){ printf("输入有误,您输入的下标重复,请重新输入!\n"); k--; flag = 1; break; } } if(flag == 0){ //输入完全正确情况下 M.data[k].i = i; M.data[k].j = j; M.data[k].e = e; } } } //对三元组表示的稀疏矩阵进行排序 Order(M); printf("*矩阵已完成创建!*\n"); return OK; } //输出稀疏矩阵M voidPrintSMatrix(TSMatrix M){ printf("\t-----------------"); printf("\n"); printf("\t%c\t%c\t%c",'i','j','e'); printf("\n"); printf("\t-----------------"); printf("\n"); if(M.tu == 0) //如果为空 printf("\t这是一个空的矩阵\n"); else{ for(int k=1; k<=M.tu; k++){ printf("\t%d\t%d\t%d",M.data[k].i,M.data[k].j,M.data[k].e); printf("\n"); } } printf("\t-----------------"); printf("\n\n"); } //查找三元组表示的稀疏矩阵M中,第row行,第col列元素,若不为0则用e返回其值 StatusFindElem(TSMatrix M, int row, int col, ElemType &e){ for(int k=1; k<=M.tu; k++){ if(row==M.data[k].i &&col==M.data[k].j){ e = M.data[k].e; printf("*元素已找到:*\n"); printf("%d\n", e); return OK; } } //找不到 printf("对不起,不存在此元素!\n"); return ERROR; } //在三元组表示的稀疏矩阵M,第row行,第col列位置插入元素e StatusInsertElem(TSMatrix &M, int row, int col, ElemType e){ int i, t, p; if(M.tu >= MAXSIZE){ //当前三元组表已满 printf("当前三元组表已满,操作失败!\n"); return ERROR; } if(row>M.mu || col>M.nu || row<1|| col<1){ //插入位置越界, // 不在1~mu或1~nu之间 printf("插入位置越界,请在此矩阵的行列数内操作。操作失败!\n"); return ERROR; } p = 1; //标志新元素应该插入的位置 if(M.tu == 0){ //插入前矩阵M 为空矩阵 ,直接插入 M.data[p].i = row; M.data[p].j = col; M.data[p].e = e; M.tu++; printf("*元素已插入!*\n"); return OK; } for(t=1; t<=M.tu; t++){ //寻找合适的位置 if(row > M.data[t].i) p++; else if((row==M.data[t].i) &&(col>=M.data[t].j)) p++; else if((row==M.data[t].i) &&(col==M.data[t].j)){ //插入前,该位 // 置元素已经存在 M.data[t].e=e; printf("*元素已插入!*\n"); return OK; } } for(i=M.tu; i>=p; i--){ //移动p之后的元素 M.data[i+1].i = M.data[i].i; M.data[i+1].j = M.data[i].j; M.data[i+1].e = M.data[i].e; } //插入新元素 M.data[p].i = row; M.data[p].j = col; M.data[p].e = e; M.tu++; printf("*元素已插入!*\n"); return OK; } //在三元组表示的稀疏矩阵M,删除第row行,第col列位置元素,并用e返回 StatusDeleteElem(TSMatrix &M, int row, int col, ElemType &e){ int i, t, p=0; if(M.tu == 0){ //矩阵如果为空 printf("操作失败!这是个空矩阵!\n"); return ERROR; } if(row>M.mu || col>M.nu || row<1|| col<1){ //删除位置越界,不在1~mu // 或1~nu之间 printf("删除位置越界,请在此矩阵的行列数内操作。操作失败!\n"); return ERROR; } for(t=1; t<=M.tu; t++){ //寻找合适的删除位置 if((row==M.data[t].i) &&(col==M.data[t].j)) p = t; } if(p == 0){ printf("删除失败,不存在此元素!\n"); return ERROR; }else{ e = M.data[p].e; for(; p M.data[p].i = M.data[p+1].i; M.data[p].j = M.data[p+1].j; M.data[p].e = M.data[p+1].e; } M.data[p].i = 0; //把最后一个元素置为0 M.data[p].j = 0; M.data[p].e = 0; } M.tu--; printf("*元素已删除: *\n"); printf("%d\n", e); return OK; } //判断是否为空矩阵 StatusIsEmptyMatrix(TSMatrix M){ if(M.tu == 0){ printf("*这是一个空矩阵!*\n"); }else printf("*这是一个非空矩阵!*\n"); return OK; } //由稀疏矩阵M复制得到T Status CopySMatrix(TSMatrixM, TSMatrix &T){ if(T.tu != 0) //原来T为非空 DestroySMatrix(T); T.mu = M.mu; T.nu = M.nu; T.tu = M.tu; for(int k=1; k<=M.tu; k++){ T.data[k].i = M.data[k].i; T.data[k].j = M.data[k].j; T.data[k].e = M.data[k].e; } return OK; } //求和Q = M + N StatusAddSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q){ ElemType t; int k=1, a, b; // a,b记下已经访问了几个 int flag[50]; //flag用来标志 N 表中哪个数据已经用过 if(Q.tu != 0) //原来Q为非空 DestroySMatrix(Q); if(M.tu == 0){ CopySMatrix(N, Q); printf("*矩阵已完成相加!*\n"); return OK; }else if(N.tu == 0){ CopySMatrix(M, Q); printf("*矩阵已完成相加!*\n"); return OK; } if(M.mu!=N.mu || M.nu!=N.nu){ printf("对不起,两个矩阵的行列号大小不相等不能相加!\n"); return ERROR; } Q.mu = M.mu; Q.nu = M.nu; a = 0; b = 0; for(int x=1; x<=49; x++) flag[x] = 0; for(int p1=1; p1<=M.tu; p1++){ for(int p2=1; p2<=N.tu; p2++){ if(M.data[p1].i ==N.data[p2].i){ //行号相等 if(M.data[p1].j ==N.data[p2].j){ //且列号相等 flag[p2] = 1; //为 1 表示此数据已经用过 a++; b++; //M, N访问数各加1 t = M.data[p1].e +N.data[p2].e; if(t != 0){ //和为非零,插入 Q.data[k].i =M.data[p1].i; Q.data[k].j = M.data[p1].j; Q.data[k].e = t; k++; break; }else break; } else{ //行号相等,列号不等,把列号小的插入 if(M.data[p1].j Q.data[k].i =M.data[p1].i; Q.data[k].j =M.data[p1].j; Q.data[k].e =M.data[p1].e; flag[p2] = 0; k++; a++; break; }else if(flag[p2] ==0){ //N表中此数据还没访问 // 过且列号小,插入 Q.data[k].i =N.data[p2].i; Q.data[k].j =N.data[p2].j; Q.data[k].e =N.data[p2].e; flag[p2] = 1; k++; b++; } } } else{ //行号不等,把行号小的插入 if(M.data[p1].i Q.data[k].i = M.data[p1].i; Q.data[k].j = M.data[p1].j; Q.data[k].e = M.data[p1].e; a++; k++; break; } else if(flag[p2] == 0){ Q.data[k].i = N.data[p2].i; Q.data[k].j = N.data[p2].j; Q.data[k].e = N.data[p2].e; flag[p2] = 1; k++; b++; } } } } if(a while(a Q.data[k].i = M.data[a+1].i; Q.data[k].j = M.data[a+1].j; Q.data[k].e = M.data[a+1].e; k++; a++; } }else if(b while(b Q.data[k].i = N.data[b+1].i; Q.data[k].j = N.data[b+1].j; Q.data[k].e = N.data[b+1].e; k++; b++; } } Q.tu = k-1; printf("*矩阵已完成相加!*\n"); return OK; } //求差Q = M - N StatusSubSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q){ ElemType t; int k=1, a, b; // a,b记下已经访问了几个 int flag[50]; //用来标志 N 表中哪个数据已经用过 if(Q.tu != 0) //原来Q为非空 DestroySMatrix(Q); if(M.tu == 0){ //被减数为空 CopySMatrix(N, Q); for(int k=1; k<=N.tu; k++) Q.data[k].e = -Q.data[k].e; //变为负的 printf("*矩阵已完成相减!*\n"); return OK; }else if(N.tu == 0){ //减数为空 CopySMatrix(M, Q); printf("*矩阵已完成相减!*\n"); return OK; } if(M.mu!=N.mu || M.nu!=N.nu){ printf("对不起,两个矩阵的行列号大小不相等不能相减!\n"); return ERROR; } Q.mu = M.mu; Q.nu = M.nu; a = 0; b = 0; for(int x=1; x<=49; x++) flag[x] = 0; for(int p1=1; p1<=M.tu; p1++){ for(int p2=1; p2<=N.tu; p2++){ if(M.data[p1].i ==N.data[p2].i){ //行号相等 if(M.data[p1].j ==N.data[p2].j){ //且列号相等 flag[p2] = 1; //为 1 表示此数据已经用过 a++; b++; //M, N访问数各加1 t = M.data[p1].e -N.data[p2].e; if(t != 0){ //差为非零,插入 Q.data[k].i =M.data[p1].i; Q.data[k].j = M.data[p1].j; Q.data[k].e = t; k++; break; } else break; } //行号相等,列号不等,把列号小的插入 else{ if(M.data[p1].j Q.data[k].i =M.data[p1].i; Q.data[k].j =M.data[p1].j; Q.data[k].e =M.data[p1].e; flag[p2] = 0; k++; a++; break; }else if(flag[p2] ==0){ //N表中此数据还没访问过 且列号小,插入 Q.data[k].i =N.data[p2].i; Q.data[k].j =N.data[p2].j; Q.data[k].e =-N.data[p2].e; //减数要变为负的 flag[p2] = 1; k++; b++; } } } else{ //行号不等,把行号小的插入 if(M.data[p1].i Q.data[k].i = M.data[p1].i; Q.data[k].j = M.data[p1].j; Q.data[k].e = M.data[p1].e; a++; k++; break; } else if(flag[p2] == 0){ Q.data[k].i = N.data[p2].i; Q.data[k].j = N.data[p2].j; Q.data[k].e =-N.data[p2].e; flag[p2] = 1; k++; b++; } } } } if(a while(a Q.data[k].i = M.data[a+1].i; Q.data[k].j = M.data[a+1].j; Q.data[k].e = M.data[a+1].e; k++; a++; } }else if(b while(b Q.data[k].i = N.data[b+1].i; Q.data[k].j = N.data[b+1].j; Q.data[k].e = -N.data[b+1].e; k++; b++; } } Q.tu = k-1; printf("*矩阵已完成相减!*\n"); return OK; } //求积Q = M * N StatusMultSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q){ if(M.nu != N.mu){ printf("操作失败!第一个矩阵的列数不等于第二个矩阵的行数!\n"); return ERROR; } int a[10][10]; //先用数组将结果保存 int t = 1; if(Q.tu != 0) //原来Q为非空 DestroySMatrix(Q); Q.mu = M.mu; Q.nu = N.nu; Q.tu = 0; for(int k=1; k<=M.tu; k++){ for(int p=1; p<=N.tu; p++){ if(M.data[k].j ==N.data[p].i){ //凡是第一个矩阵的列号等于第 // 二个矩阵的行号的都把结果相加 // 分别放入以第一个矩阵行号为i // 第二个矩阵列号为j的数组中 a[M.data[k].i][N.data[p].j] +=M.data[k].e * N.data[p].e; } } } for(int m=1; m<10; m++){ //放入Q中 for(int n=1; n<10; n++){ if(a[m][n] != 0){ Q.data[t].e = a[m][n]; Q.data[t].i = m; Q.data[t].j = n; t++; } } } Q.tu = t - 1; printf("*矩阵已完成相乘*\n"); return OK; } //由稀疏矩阵M的转置矩阵T StatusTransposeSMatrix(TSMatrix M, TSMatrix &T){ //快速转置 int col, t, p, q; int num[50], cpot[50], data[50]; if(T.tu != 0) DestroySMatrix(T); //原来T为非空 T.mu = M.mu; T.nu = M.nu; T.tu = M.tu; if(T.tu){ for(col=1; col<=M.nu; col++) num[col] = 0; //初始化为0 for(t=1; t<=M.tu; t++) ++num[M.data[t].j]; //求M中每一列含非零元素个数 cpot[1] = 1; //求第col列中第一个非零元素在T.data的序号 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]; //同一行中的位置加1 } } printf("*矩阵已完成转置!*\n"); return OK; } //设计者信息 void Designer(){ printf("\t\t Design By XXX\n"); printf("\t\t_______________________\n"); printf("\t\t| 姓名 : | XXX |\n"); printf("\t\t|-----------------------\n"); printf("\t\t| 班级: | 计科1 |\n"); printf("\t\t|-----------------------\n"); printf("\t\t| 学号: | 3112005763|\n"); printf("\t\t~~~~~~~~~~~~~~~~~~~~~~~\n"); printf("\tCopyright @CKW, All RightsReserved\n\n"); } //欢迎界面 void Welcome(){ printf("\t\t欢迎来到《稀疏矩阵》中心!\n"); printf("\t\t请输入你想要进行的操作:\n"); printf("\ta.【创建稀疏矩阵】b.【输出稀疏矩阵】 c.【转置稀疏矩阵】\n"); printf("\td.【插入元素】\t e.【删除元素】\tf.【查找元素】\n"); printf("\tg.【矩阵相加】\t h.【矩阵相减】\ti.【矩阵相乘】\n"); printf("\tj.【矩阵判空】\t k.【销毁矩阵】\tl.【矩阵复制】\n"); printf("\t\t\t0.【退出系统!】\n\n"); } //主函数 void main() { TSMatrix M, T, N, Q; int row, col; char c, n; ElemType e; Designer(); Welcome(); while(1){ printf("【请输入你想要进行的操作:】\n"); scanf(" %c", &n); //此处输入的是字符,因为字符比数字容易处理 // %c前面有个空格是因为scanf()的缓冲区处理 if(n == '0') //如果输入0字符即退出系统 break; //a ~ l之间 else if('a'<=n &&n<='l'){ switch(n){ case 'a': { printf("请选择你想要创建哪个矩阵:\n"); printf("请输入 M 或者 N \n"); while(1){ scanf("%c", &c); if(c == 'M'){ CreateSMatrix(M); break; }else if(c == 'N'){ CreateSMatrix(N); break; }else{ printf("你输入有误,请重新输入!\n"); } } break; } case 'b': { printf("请选择你想要输出的矩阵:\n"); printf("M(原矩阵)N(原矩阵)T(复制or转置矩阵)Q(运 算后的矩阵)\n"); while(1){ scanf("%c", &c); if(c == 'M'){ PrintSMatrix(M); break; }else if(c == 'N'){ PrintSMatrix(N); break; }else if(c == 'T'){ PrintSMatrix(T); break; }else if(c == 'Q'){ PrintSMatrix(Q); break; }else{ printf("你输入有误,请重新输入!\n"); } } break; } case 'c': { printf("请选择你想要转置的矩阵:\n"); printf("请输入 M 或者 N 或者Q\n"); while(1){ scanf("%c", &c); if(c == 'M'){ TransposeSMatrix(M, T); break; }else if(c == 'N'){ TransposeSMatrix(N, T); break; }else if(c == 'Q'){ TransposeSMatrix(Q, T);break; }else{ printf("你输入有误,请重新输入!\n"); } } break; } case 'd': { printf("请选择你想要插入元素的矩阵:\n"); printf("请输入 M 或者 N 或者 Q 或者 T\n"); while(1){ scanf("%c", &c); if(c == 'M'){ printf("请输入你想要插入元素的位置及该 元素(X,X,X):\n"); scanf("%d,%d,%d", &row, &col, &e); InsertElem(M,row, col, e); break; }else if(c == 'N'){ printf("请输入你想要插入元素的位置及该 元素(X,X,X):\n"); scanf("%d,%d,%d", &row, &col, &e); InsertElem(N,row, col, e); break; }else if(c == 'Q'){ printf("请输入你想要插入元素的位置及该 元素(X,X,X):\n"); scanf("%d,%d,%d", &row, &col, &e); InsertElem(Q,row, col, e); break; }else if(c == 'T'){ printf("请输入你想要插入元素的位置及该 元素(X,X,X):\n"); scanf("%d,%d,%d", &row, &col, &e); InsertElem(T,row, col, e); break; }else{ printf("你输入有误,请重新输入!\n"); } } break; } case 'e': { printf("请选择你想要删除元素的矩阵:\n"); printf("请输入 M 或者 N 或者 Q 或者 T\n"); while(1){ scanf(" %c",&c); if(c == 'M'){ printf("请输入你想要删除元素的位置(X,X):\n"); scanf("%d,%d", &row, &col); DeleteElem(M,row, col, e); break; }else if(c == 'N'){ printf("请输入你想要删除元素的位置(X,X):\n"); scanf("%d,%d", &row, &col); DeleteElem(N,row, col, e); break; }else if(c == 'Q'){ printf("请输入你想要删除元素的位置(X,X):\n"); scanf("%d,%d", &row, &col); DeleteElem(Q,row, col, e); break; }else if(c == 'T'){ printf("请输入你想要删除元素的位置(X,X):\n"); scanf("%d,%d", &row, &col); DeleteElem(T,row, col, e); break; }else{ printf("你输入有误,请重新输入!\n"); } } break; } case 'f': { printf("请选择你想要查找元素的矩阵:\n"); printf("请输入 M 或者 N 或者 Q 或者 T\n"); while(1){ scanf("%c", &c); if(c == 'M'){ printf("请输入你想要查找元素的位置(X,X):\n"); scanf("%d,%d", &row, &col); FindElem(M,row, col, e); break; }else if(c == 'N'){ printf("请输入你想要查找元素的位置(X,X):\n"); scanf("%d,%d", &row, &col); FindElem(N,row, col, e); break; }else if(c == 'Q'){ printf("请输入你想要查找元素的位置(X,X):\n"); scanf("%d,%d",&row, &col); FindElem(Q,row, col, e); break; }else if(c == 'T'){ printf("请输入你想要查找元素的位置(X,X):\n"); scanf("%d,%d", &row, &col); FindElem(T,row, col, e); break; }else{ printf("你输入有误,请重新输入!\n"); } } break; } case'g':AddSMatrix(M,N,Q);break; //只能是M和N相加,相减,相乘 case 'h': SubSMatrix(M, N, Q);break; case 'i': MultSMatrix(M, N, Q);break; case 'j': { printf("请选择你想要判空的矩阵:\n"); printf("请输入 M 或者 N 或者 Q 或者 T\n"); while(1){ scanf("%c", &c); if(c == 'M'){ IsEmptyMatrix(M); break; }else if(c == 'N'){ IsEmptyMatrix(N); break; }else if(c == 'Q'){ IsEmptyMatrix(Q); break; }else if(c == 'T'){ IsEmptyMatrix(T); break; }else{ printf("你输入有误,请重新输入!\n"); } } break; } case 'k': { printf("请选择你想要销毁的矩阵:\n"); printf("请输入 M 或者 N 或者 Q 或者 T\n"); while(1){ scanf("%c", &c); if(c == 'M'){ DestroySMatrix(M); printf("*矩阵已完成销毁!*\n"); //把打印语句写在这里而不写在函数里是因为 //别的函数会用到这个函数,避免多余的麻烦 break; }else if(c == 'N'){ DestroySMatrix(N); printf("*矩阵已完成销毁!*\n"); break; }else if(c == 'Q'){ DestroySMatrix(Q); printf("*矩阵已完成销毁!*\n"); break; }else if(c == 'T'){ DestroySMatrix(T); printf("*矩阵已完成销毁!*\n"); break; }else{ printf("你输入有误,请重新输入!\n"); } } break; } case 'l': { printf("请选择你想要复制哪个矩阵:\n"); printf("请输入 M 或者 N 或者Q\n"); while(1){ scanf("%c", &c); if(c == 'M'){ CopySMatrix(M,T); printf("*矩阵已完成复制!*\n"); //把打印语句写在这里而不写在函数里是因为 //别的函数会用到这个函数,避免多余的麻烦 break; }else if(c == 'N'){ CopySMatrix(N,T); printf("*矩阵已完成复制!*\n"); break; }else if(c == 'Q'){ CopySMatrix(Q,T); printf("*矩阵已完成复制!*\n"); break; }else{ printf("你输入有误,请重新输入!\n"); } } break; } default: break; } }else{ printf("对不起,您输入的操作有误,请重新输入!\n"); } } printf("\t\t\t已安全退出,感谢使用!\n"); } 4.调试与分析 问题1: 创建三元组时,为了可以满足任意输入的无序数据也能构成三元组 解决方法:对三元组表示的稀疏矩阵进行排序 调用方法voidOrder(TSMatrix &M) 问题2: 创建稀疏矩阵时,为了满足输入的容错性 解决方法:使用了循环的方法while( 1 ){ 输入正确时跳出循环 } 问题3: 如何销毁稀疏矩阵 解决方法:要想销毁一个三元组表示的矩阵就必须销毁四部分:1.M.mu, 2.M.nu, 3.M.tu 4.M.data[] 可以将M.mu, M.nu, M.tu置为0即可销毁 M.mu, M.nu, M.tu 因为M.data[]用数组实现,又数组为静态分配,故销毁数组只能 置其内容为0,而不能释放其空间。所以利用 for(int k=1; k<=num;k++){ M.data[k].i = 0; M.data[k].j = 0; M.data[k].e= 0; }将M.data[]置为0即可销毁之 问题4: 如何在矩阵中插入新元素 解决方法:先找到要插入的行列号在三元组中的位置,然后向后移动此位置 以后的所有元素,再插入。 问题5: 如何进行矩阵求和。 解决方法:分为3大类。1,行号不相等的,把行号小的插入。2,行号相等 而列号不相等的,把列号小的插入。3,行列号都相等的,求和 后如果非零即插入。最后,如果M表未完,即把剩下的插入。 如果N表未完,即把剩下的插入。 问题6: 如何进行矩阵相乘。 解决方法:先用数组将结果保存,再用数组逐一给三元组赋值。也即是,凡 是第一个矩阵的列号等于第二个矩阵的行号的都把结果相乘,分 别放入以第一个矩阵行号为i第二个矩阵列号为j的数组a[i][j] 中,再用数组逐一给三元组赋值。 问题7: 矩阵如何进行快速转置。 解决方法: 先计算出矩阵M中的每一列的第一个非零元素在T.data中的位 置,再进行相应插入。 问题8: scanf函数输入时键盘缓冲区\n的问题。也即对于scanf("%c", &j)来说,回 车键也作为一种输入。当我上一行有回车时,使用scanf("%c", &j)出现问题。 解决方法:可以用scanf("%c", &j)来解决。注意%c前面有一个空格。这个 空格有吸收回车和空格的功能,吸收之后要求buffer给一个字节,直到这个字节不是回车或空格,此时把这个字节交给下一个格式串。问题解决。 5.运行测试 请读者自行测试。