数据结构与使用
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100 // 最大非零元素个数
#define MAXDIM 20 // 最大行列数
// 三元组结构体
typedef struct {
int row, col; // 行号、列号
int value; // 元素值
} Triple;
// 稀疏矩阵结构体(三元组顺序表)
typedef struct {
Triple data[MAXSIZE + 1]; // 存储三元组,下标从1开始
int rows, cols, nums; // 矩阵行数、列数、非零元素个数
} SparseMatrix;
// 初始化稀疏矩阵
void initMatrix(SparseMatrix *mat, int r, int c) {
mat->rows = r;
mat->cols = c;
mat->nums = 0;
}
// 插入三元组(按行优先)
int insertTriple(SparseMatrix *mat, int r, int c, int v) {
if (r < 1 || r > mat->rows || c < 1 || c > mat->cols) {
printf("位置无效!\n");
return 0;
}
if (mat->nums >= MAXSIZE) {
printf("存储空间已满!\n");
return 0;
}
// 查找插入位置(行优先)
int i = mat->nums;
while (i >= 1 && (mat->data[i].row > r ||
(mat->data[i].row == r && mat->data[i].col > c))) {
mat->data[i + 1] = mat->data[i];
i--;
}
mat->data[i + 1].row = r;
mat->data[i + 1].col = c;
mat->data[i + 1].value = v;
mat->nums++;
return 1;
}
// 从三元组输入稀疏矩阵
void inputMatrix(SparseMatrix *mat) {
int r, c, v, n;
printf("请输入非零元素个数: ");
scanf("%d", &n);
printf("请按行优先顺序输入%d个三元组(行 列 值):\n", n);
for (int i = 0; i < n; i++) {
scanf("%d %d %d", &r, &c, &v);
if (!insertTriple(mat, r, c, v)) {
i--; // 输入错误重新输入
}
}
}
// 矩阵相加
int addMatrix(SparseMatrix a, SparseMatrix b, SparseMatrix *result) {
if (a.rows != b.rows || a.cols != b.cols) {
return 0; // 行列数不匹配
}
initMatrix(result, a.rows, a.cols);
int i = 1, j = 1;
while (i <= a.nums && j <= b.nums) {
int aRow = a.data[i].row, aCol = a.data[i].col;
int bRow = b.data[j].row, bCol = b.data[j].col;
if (aRow < bRow || (aRow == bRow && aCol < bCol)) {
insertTriple(result, aRow, aCol, a.data[i].value);
i++;
} else if (aRow > bRow || (aRow == bRow && aCol > bCol)) {
insertTriple(result, bRow, bCol, b.data[j].value);
j++;
} else {
// 行列相同,值相加
int sum = a.data[i].value + b.data[j].value;
if (sum != 0) { // 和不为零才存储
insertTriple(result, aRow, aCol, sum);
}
i++;
j++;
}
}
// 处理剩余元素
while (i <= a.nums) {
insertTriple(result, a.data[i].row, a.data[i].col, a.data[i].value);
i++;
}
while (j <= b.nums) {
insertTriple(result, b.data[j].row, b.data[j].col, b.data[j].value);
j++;
}
return 1;
}
// 矩阵相减
int subMatrix(SparseMatrix a, SparseMatrix b, SparseMatrix *result) {
// 复制矩阵b并取负值
SparseMatrix bNeg = b;
for (int i = 1; i <= bNeg.nums; i++) {
bNeg.data[i].value = -bNeg.data[i].value;
}
return addMatrix(a, bNeg, result); // 利用加法实现减法
}
// 矩阵相乘
int mulMatrix(SparseMatrix a, SparseMatrix b, int result[MAXDIM][MAXDIM]) {
if (a.cols != b.rows) {
return 0; // 列数不等于行数,无法相乘
}
// 初始化结果矩阵为0
for (int i = 0; i < a.rows; i++) {
for (int j = 0; j < b.cols; j++) {
result[i][j] = 0;
}
}
// 计算乘积
for (int i = 1; i <= a.nums; i++) {
int aRow = a.data[i].row - 1; // 转为0基索引
int aCol = a.data[i].col - 1;
int aVal = a.data[i].value;
for (int j = 1; j <= b.nums; j++) {
if (b.data[j].row - 1 == aCol) { // 找到匹配的列和行
int bCol = b.data[j].col - 1;
int bVal = b.data[j].value;
result[aRow][bCol] += aVal * bVal;
}
}
}
return 1;
}
// 将三元组矩阵转换为普通二维数组
void tripleToMatrix(SparseMatrix mat, int arr[MAXDIM][MAXDIM]) {
// 初始化数组为0
for (int i = 0; i < mat.rows; i++) {
for (int j = 0; j < mat.cols; j++) {
arr[i][j] = 0;
}
}
// 填充非零元素
for (int i = 1; i <= mat.nums; i++) {
int row = mat.data[i].row - 1; // 转为0基索引
int col = mat.data[i].col - 1;
arr[row][col] = mat.data[i].value;
}
}
// 打印二维数组形式的矩阵
void printMatrix(int arr[MAXDIM][MAXDIM], int rows, int cols) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%4d", arr[i][j]);
}
printf("\n");
}
}
// 主函数
int main() {
SparseMatrix a, b, res;
int op;
int row1, col1, row2, col2;
int resultArr[MAXDIM][MAXDIM];
printf("稀疏矩阵运算器\n");
printf("1. 矩阵相加\n2. 矩阵相减\n3. 矩阵相乘\n请选择操作: ");
scanf("%d", &op);
// 输入第一个矩阵
printf("请输入第一个矩阵的行数和列数: ");
scanf("%d %d", &row1, &col1);
if (row1 > MAXDIM || col1 > MAXDIM) {
printf("矩阵尺寸超过最大值%d!\n", MAXDIM);
return 1;
}
initMatrix(&a, row1, col1);
inputMatrix(&a);
// 输入第二个矩阵
printf("请输入第二个矩阵的行数和列数: ");
scanf("%d %d", &row2, &col2);
if (row2 > MAXDIM || col2 > MAXDIM) {
printf("矩阵尺寸超过最大值%d!\n", MAXDIM);
return 1;
}
initMatrix(&b, row2, col2);
inputMatrix(&b);
// 执行操作并输出结果
printf("\n运算结果:\n");
switch (op) {
case 1:
if (addMatrix(a, b, &res)) {
tripleToMatrix(res, resultArr);
printMatrix(resultArr, res.rows, res.cols);
} else {
printf("相加失败:矩阵行数或列数不匹配!\n");
}
break;
case 2:
if (subMatrix(a, b, &res)) {
tripleToMatrix(res, resultArr);
printMatrix(resultArr, res.rows, res.cols);
} else {
printf("相减失败:矩阵行数或列数不匹配!\n");
}
break;
case 3:
if (mulMatrix(a, b, resultArr)) {
printMatrix(resultArr, a.rows, b.cols);
} else {
printf("相乘失败:第一个矩阵的列数与第二个矩阵的行数不相等!\n");
}
break;
default:
printf("无效操作!\n");
}
return 0;
}