稀疏矩阵的转置和加法实验报告

实验八   数组操作

(一)实验目的

1)通过实验理解稀疏矩阵。

   2)通过实验掌握稀疏矩阵的存储结构。

   3)通过实验掌握稀疏矩阵的逆置和相加操作.

必须达到的最少程序行数为150行.

(二)实验项目内容(尽可能写具体

1)    稀疏矩阵的定义。

2)    稀疏矩阵的逆置操作。

3)    稀疏矩阵的相加操作。

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <windows.h>
  4 
  5 #define MAXSIZE 1000
  6 #define OK 0
  7 
  8 #define MALLOC_FAIL -1            // 表示分配空间时发生错误
  9 #define EMPTY_MATRIX -2            // 表示正尝试对一个空矩阵进行运算操作
 10 #define MATRIX_NOT_MATCH -3        // 表示尝试对不符合运算条件的矩阵进行运算操作(例如非相同行数列数矩阵相加)
 11 
 12 /* ----------- 结构体声明部分 ---------------- */
 13 typedef struct
 14 {
 15     int row;    // 非零元的行下标
 16     int col;    // 非零元的列下标
 17     int e;        // 非零元的值
 18 } Triple;        //三元组结构
 19 
 20 typedef struct
 21 {
 22     Triple *data;                // 非零元素的元素表
 23     int rownum;                    // 矩阵的行数
 24     int colnum;                    // 矩阵的列数
 25     int num;                    // 矩阵非零元的个数
 26 } TSMatrix, *PTSMatrix;
 27 
 28 /* ----------- 函数声明部分 ------------------ */
 29 // 初始化稀疏矩阵结构
 30 int TSMatrix_Init(TSMatrix *M);
 31 
 32 // 以三元组的方式输出稀疏矩阵
 33 void TSMatrix_PrintTriple(TSMatrix *M);
 34 
 35 // 从一个二维数组(普通矩阵)创建一个稀疏矩阵
 36 TSMatrix *TSMatrix_Create(int *a, int row, int col);
 37 
 38 // 从键盘录入数据创建一个稀疏矩阵
 39 TSMatrix *TSMatrix_CreateFromInput();
 40 
 41 // 求稀疏矩阵 M 的转置矩阵 T
 42 int TSMatrix_FastTranspose(TSMatrix M, TSMatrix *T);
 43 
 44 // 如果稀疏矩阵 M 和 N 的行数的列数相同,计算 Q = M + N
 45 int TSMatrix_Add(TSMatrix M, TSMatrix N, TSMatrix *Q);
 46 
 47 
 48 // 初始化稀疏矩阵结构
 49 int TSMatrix_Init(TSMatrix *M)
 50 {
 51     M->data = (Triple *)malloc(MAXSIZE * sizeof(Triple));
 52 
 53     if (!M->data)
 54         return MALLOC_FAIL;
 55 
 56     M->num = 0;
 57     M->colnum = 0;
 58     M->rownum = 0;
 59 
 60     return OK;
 61 }
 62 
 63 
 64 // 以三元组的方式输出稀疏矩阵
 65 void TSMatrix_PrintTriple(TSMatrix *M)
 66 {
 67     int i;
 68 
 69     if (0 == M->num)
 70     {
 71         printf("稀疏矩阵为空!\n");
 72         return;
 73     }
 74 
 75     printf("  i    j    v  \n");
 76     printf("===============\n");
 77 
 78     for (i = 0; i < M->num; i++)
 79     {
 80 
 81         printf("%3d  %3d  %3d\n", M->data[i].row, M->data[i].col, M->data[i].e);
 82     }
 83 
 84     printf("===============\n");
 85 }
 86 
 87 // 求稀疏矩阵 M 的转置矩阵 T
 88 int TSMatrix_FastTranspose(TSMatrix M, TSMatrix *T)
 89 {
 90     int *num, *cpot, i, t;
 91 
 92     // 如果矩阵 M 为空矩阵,返回错误信息
 93     if (M.num == 0)
 94         return EMPTY_MATRIX;
 95 
 96     // 分配临时的工作空间
 97     num = (int *)malloc((M.colnum + 1) * sizeof(int));
 98     cpot = (int *)malloc((M.colnum + 1) * sizeof(int));
 99 
100     // 如果临时的工作空间分配不成功
101     if (num == NULL || cpot == NULL)
102         return MALLOC_FAIL;
103 
104     // 初始化临时工作空间(把 num 数组用 0 填充)
105     for (i = 1; i <= M.rownum; i++)
106         num[i] = 0;
107 
108     // 统计倒置后每行的元素数量(即统计倒置前矩阵每列元素的数量)
109     for (i = 1; i <= M.num; i++)
110         num[M.data[i - 1].col]++;
111 
112     // 设置 T 矩阵每行首个非零元的位置
113     cpot[1] = 0;
114     for (i = 2; i <= M.colnum; i++)
115         cpot[i] = cpot[i - 1] + num[i - 1];
116 
117     // 把 T 矩阵的信息清空
118     TSMatrix_Init(T);
119 
120     // 把矩阵 M 的信息填充到 T 中。
121     // 矩阵倒置以后,T 的行数等于 M 的列数,T 的列数等于 M 的行数
122     T->num = M.num;
123     T->colnum = M.rownum;
124     T->rownum = M.colnum;
125 
126     // 对 M 矩阵中每个非零元素进行转置操作
127     for (i = 0; i < M.num; i++)
128     {
129         t = cpot[M.data[i].col];
130 
131         T->data[t].col = M.data[i].row;
132         T->data[t].row = M.data[i].col;
133         T->data[t].e = M.data[i].e;
134 
135         ++cpot[M.data[i].col];
136     }
137 
138     // 转置完成后释放临时工作空间
139     free(num);
140     free(cpot);
141 
142     return OK;
143 }
144 
145 // 如果稀疏矩阵 M 和 N 的行数的列数相同,计算 Q = M + N
146 int TSMatrix_Add(TSMatrix M, TSMatrix N, TSMatrix *Q)
147 {
148     int i = 0, j = 0, k = 0;
149 
150     if (M.colnum != N.colnum || M.rownum != N.rownum)
151         return MATRIX_NOT_MATCH;
152 
153     // 填充结果矩阵信息
154     TSMatrix_Init(Q);
155     Q->colnum = M.colnum;
156     Q->rownum = M.rownum;
157     Q->num = 0;
158 
159     while (i < M.num && j < N.num)
160     {
161         // 如果 i j 指向元素是同一行的元素
162         if (M.data[i].row == N.data[j].row)
163         {
164             // 如果 i 和 j 指向的元素指向的是同一个元素
165             if (M.data[i].col == N.data[j].col)
166             {
167                 Q->data[k].row = M.data[i].row;
168                 Q->data[k].col = M.data[i].col;
169                 Q->data[k].e = M.data[i].e + N.data[j].e;
170                 i++;
171                 j++;
172                 if(Q->data[k].e != 0)   //如果相加之后的值为0,则不在三元组中保存
173                 {
174                     k++;
175                     Q->num++;
176                 }
177             }
178             // 如果 i 指向元素的列下标大于 j 指向元素的列下标
179             // 把下标小(j 指向的元素)的放入到 Q 矩阵中
180             else if (M.data[i].col > N.data[j].col)
181             {
182                 Q->data[k].row = N.data[j].row;
183                 Q->data[k].col = N.data[j].col;
184                 Q->data[k].e = N.data[j].e;
185                 Q->num++;
186 
187                 j++;
188                 k++;
189             }
190             // 如果 i 指向元素的列下标小于 j 指向元素的列下标
191             // 把下标小(i 指向的元素)的放入到 Q 矩阵中
192             else if (M.data[i].col < N.data[j].col)
193             {
194                 Q->data[k].row = M.data[i].row;
195                 Q->data[k].col = M.data[i].col;
196                 Q->data[k].e = M.data[i].e;
197                 Q->num++;
198 
199                 i++;
200                 k++;
201             }
202         }
203         // 如果 i 指向的元素行下标大于 j 指向元素的行下标
204         else if (M.data[i].row > N.data[j].row)
205         {
206             Q->data[k].row = N.data[j].row;
207             Q->data[k].col = N.data[j].col;
208             Q->data[k].e = N.data[j].e;
209             Q->num++;
210 
211             k++;
212             j++;
213         }
214         // 如果 i 指向元素行下标小于 j 指向元素的行下标
215         else if (M.data[i].row < N.data[j].row)
216         {
217             Q->data[k].row = M.data[i].row;
218             Q->data[k].col = M.data[i].col;
219             Q->data[k].e = M.data[i].e;
220             Q->num++;
221 
222             i++;
223             k++;
224         }
225     }
226 
227     // 如果还有剩余元素,按顺序把元素添加到结果矩阵中
228     while (i < M.num)
229     {
230         Q->data[k].row = M.data[i].row;
231         Q->data[k].col = M.data[i].col;
232         Q->data[k].e = M.data[i].e;
233         Q->num++;
234 
235         i++;
236         k++;
237     }
238 
239     while (j < N.num)
240     {
241         Q->data[k].row = N.data[j].row;
242         Q->data[k].col = N.data[j].col;
243         Q->data[k].e = N.data[j].e;
244 
245         Q->num++;
246 
247         j++;
248         k++;
249     }
250 
251     return OK;
252 }
253 
254 // 从一个二维数组创建一个稀疏矩阵
255 TSMatrix *TSMatrix_Create(int *a, int row, int col)
256 {
257     int i, j;
258     TSMatrix *P = (TSMatrix *)malloc(sizeof(TSMatrix));
259     TSMatrix_Init(P);
260 
261     // 设置稀疏矩阵的行数和列数
262     P->rownum = row;
263     P->colnum = col;
264 
265     for (i = 0; i < row; i++)
266     {
267         for (j = 0; j < col; j++)
268         {
269             // 如果第 i+1 行第 i+1 列元素是非零元素
270             if (0 != *(a + i * col + j))
271             {
272                 // 把非零元的元素和位置信息保存到稀疏矩阵中
273                 P->data[P->num].e = *(a + i * col + j);
274                 P->data[P->num].row = i + 1;
275                 P->data[P->num].col = j + 1;
276 
277                 // 把稀疏矩阵中的非零元个数加一
278                 P->num++;
279             }
280         }
281     }
282 
283     return P;
284 }
285 
286 //从输入中创建矩阵
287 TSMatrix *TSMatrix_CreateFromInput()
288 {
289     int *a, i, j, k;
290     TSMatrix *T;
291 
292     printf("请输入新创建的矩阵的行数和列数,分别输入并利用空格间开:");
293 
294     // 输入的同时对数据的有效性进行检查
295     while (2 != scanf("%d%d", &i, &j))
296         printf("无效输入,请重新输入!\n");
297 
298     // 分配临时储存输入数据的空间
299     a = (int *)malloc(i * j * sizeof(int));
300 
301     // 如果分配失败,则返回一个空指针
302     if (a == NULL)
303         return NULL;
304 
305     // 开始从键盘中读入元素
306     for (k = 0; k < i * j; k++)
307     {
308 
309         printf("请从键盘输入第 %d 行第 %d 列元素:", (k / j) + 1, (k % j) + 1);
310 
311         while (1 != scanf("%d", (a + k)))
312         {
313             printf("无效输入,请重新输入!\n");
314         }
315     }
316 
317     T = TSMatrix_Create(a, i, j);
318 
319     // 释放用于临时储存输入的空间
320     free(a);
321 
322     return T;
323 }
324 
325 /* ----------- 程序主函数 -------------------- */
326 int main()
327 {
328     int info;
329     char ch;
330 
331     // 从一个二维数组创建一个系数矩阵
332     TSMatrix *M;
333     TSMatrix *N;
334 
335     // 用来接收运算结果的空间
336     TSMatrix *T = (TSMatrix *)malloc(sizeof(TSMatrix));
337 
338     while (1)
339     {
340         fflush(stdin);
341         system("cls");
342 
343         printf(" 稀疏矩阵基本操作演示 \n");
344         printf("1. 矩阵的创建和转置\n");
345         printf("2. 矩阵的加法运算并以三元组输出结果\n");
346         printf("\n");
347         printf("Q. 退出程序\n");
348         printf("\n");
349         printf("  请输入选项:");
350 
351         scanf("%c", &ch);
352 
353         switch (ch)
354         {
355         case '1':
356             system("cls");
357 
358             M = TSMatrix_CreateFromInput();
359 
360             if (M != NULL)
361             {
362                 printf("\n\n以三元组输出稀疏矩阵:\n");
363                 TSMatrix_PrintTriple(M);
364                 printf("\n转置后稀疏矩阵的三元组输出:\n");
365                 TSMatrix_FastTranspose(*M, T);
366                 TSMatrix_PrintTriple(T);
367 
368                 system("pause");
369             }
370             else
371             {
372                 printf("创建矩阵过程发生错误");
373                 system("pause");
374             }
375 
376             break;
377         case '2':
378             system("cls");
379 
380             M = TSMatrix_CreateFromInput();
381             N = TSMatrix_CreateFromInput();
382 
383             if (M == NULL || N == NULL)
384             {
385                 printf("创建矩阵过程中发生错误!\n");
386                 system("pause");
387                 break;
388             }
389 
390             info = TSMatrix_Add(*M, *N, T);
391 
392             if (info == MATRIX_NOT_MATCH)
393             {
394                 printf("这两个矩阵不能运算呢!!  ⊙﹏⊙\n");
395             }
396             else if (info == OK)
397             {
398                 printf("\n运算结果:\n");
399                 TSMatrix_PrintTriple(T);
400             }
401 
402             system("pause");
403 
404             break;
405 
406         case 'q':
407         case 'Q':
408             exit(0);
409         }
410     }
411 
412     return 0;
413 }

猜你喜欢

转载自www.cnblogs.com/FengZeng666/p/9999513.html