当前位置: 首页 > news >正文

数据结构之稀疏矩阵与三元组表示法

稀疏矩阵的概念

在实际应用中,我们经常会遇到一些矩阵,其中大部分元素都是零,只有少量的非零元素。这种矩阵被称为稀疏矩阵。例如,在图像处理、网络分析等领域,稀疏矩阵经常出现。如果使用传统的二维数组来存储稀疏矩阵,会浪费大量的存储空间,因为大部分的数组元素都是零。因此,我们需要一种更高效的存储方法,三元组表示法就是其中之一。

三元组表示法的原理

三元组表示法的核心思想是只存储稀疏矩阵中的非零元素。对于每个非零元素,我们用一个三元组 (i, j, e) 来表示,其中 i 是元素的行号,j 是元素的列号,e 是元素的值。然后,将这些三元组按一定的顺序存储在一个顺序表中,同时记录矩阵的行数、列数和非零元素的个数。这样,我们就可以用一个较小的存储空间来存储稀疏矩阵。

完整代码如下:

#include <stdio.h>
#include <stdlib.h>  // 使用标准库的内存分配函数// 定义元素类型为整数
typedef int ElemType;// 定义三元组最大数量
#define MAXSIZE 1000// 三元组结构,用于存储矩阵中非零元素的行、列和值
typedef struct 
{int i, j;        // i 表示行号,j 表示列号ElemType e;      // e 表示元素的值
} Triple;// 三元组顺序表,用于存储稀疏矩阵
typedef struct
{int mu, nu, tu;  // mu 为矩阵的行数,nu 为矩阵的列数,tu 为非零元素的个数Triple data[MAXSIZE];  // 存储三元组的静态顺序表
} TSMatrix;// 创建一个三元组表示的稀疏矩阵
void creatTSMatrix(TSMatrix *M, int m, int n) 
{int row, col, val;int k = 0;M->mu = m;  // 设置矩阵的行数M->nu = n;  // 设置矩阵的列数printf("请输入非零元素的行、列、值,以逗号分隔,输入行号为 0 时结束:\n");while (1) {if (scanf("%d,%d,%d", &row, &col, &val) != 3){// 处理输入格式错误printf("输入格式错误,请重新输入!\n");while (getchar() != '\n');  // 清除错误输入continue;}if (row == 0) {break;  // 输入行号为 0 时结束输入}if (k >= MAXSIZE - 1){printf("非零元素数量超过最大限制!\n");break;}k++;M->data[k].i = row;M->data[k].j = col;M->data[k].e = val;}M->tu = k;  // 记录非零元素的个数
}// 输出三元组稀疏矩阵
void OutputTSMatrix(TSMatrix *M) 
{int k;printf("(");  // 输出左括号for (k = 1; k < M->tu; k++) {printf("(%d,%d,%d),", M->data[k].i, M->data[k].j, M->data[k].e);}if (M->tu > 0) {printf("(%d,%d,%d)", M->data[k].i, M->data[k].j, M->data[k].e);  // 输出最后一个元素,后面无逗号}printf(")");  // 输出右括号printf("\n");
}// 求三元组的转置矩阵三元组
void TSMatrix_Transpose(TSMatrix *M, TSMatrix *T) 
{int k, col, i;T->mu = M->nu;  // 转置矩阵的行数等于原矩阵的列数T->nu = M->mu;  // 转置矩阵的列数等于原矩阵的行数T->tu = M->tu;  // 转置矩阵的非零元素个数等于原矩阵的非零元素个数if (T->tu == 0) {printf("矩阵无有效元素,无法转置!\n");return;}k = 1;for (col = 1; col <= M->nu; col++) {  for (i = 1; i <= M->tu; i++) 		// 按列遍历原矩阵{    if (M->data[i].j == col)		// 查找所有元素中列号为 col 的元素{T->data[k].i = M->data[i].j;  // 把列号变为转置矩阵的行号T->data[k].j = M->data[i].i;  // 把行号变为转置矩阵的列号T->data[k].e = M->data[i].e;  // 值赋予k++;}}}OutputTSMatrix(T);
}int main() 
{TSMatrix *M, *T;int m = 5, n = 4;M = (TSMatrix *)malloc(sizeof(TSMatrix));T = (TSMatrix *)malloc(sizeof(TSMatrix));if (M == NULL || T == NULL) {printf("内存分配失败!\n");return 1;}creatTSMatrix(M, m, n);printf("原矩阵的三元组表示:");OutputTSMatrix(M);printf("转置矩阵的三元组表示:");TSMatrix_Transpose(M, T);free(M);  // 释放内存free(T);return 0;
}

数据结构定义

typedef struct {int i, j;ElemType e;
} Triple;typedef struct {int mu, nu, tu;Triple data[MAXSIZE];
} TSMatrix;

这里定义了两个结构体,Triple 结构体用于存储非零元素的三元组,TSMatrix 结构体用于存储稀疏矩阵的基本信息和非零元素的三元组。

创建稀疏矩阵

void creatTSMatrix(TSMatrix *M, int m, int n) {// ...
}

creatTSMatrix 函数用于创建一个三元组表示的稀疏矩阵。通过循环读取用户输入的非零元素的行、列、值,直到输入的行号为 0 时结束。这样,我们就可以将用户输入的稀疏矩阵存储为三元组表示的形式。

输出稀疏矩阵

void OutputTSMatrix(TSMatrix *M) {// ...
}

OutputTSMatrix 函数用于输出三元组稀疏矩阵。按照指定的格式输出所有非零元素的三元组,方便我们查看矩阵的存储情况。

求转置矩阵

void TSMatrix_Transpose(TSMatrix *M, TSMatrix *T) {// ...
}

TSMatrix_Transpose 函数用于求三元组的转置矩阵三元组。通过按列遍历原矩阵,将原矩阵中列号为 col 的元素的列号变为转置矩阵的行号,行号变为转置矩阵的列号,值保持不变。这样,我们就可以得到原矩阵的转置矩阵的三元组表示。

运行:

即原矩阵:0 0 3           转置后:0 0 5

                  0 0 4                         3 0 0

                  5 0 0                         0 4 0

三元组表示法的优缺点

优点

  • 节省存储空间:只存储非零元素,避免了大量零元素的存储,节省了存储空间。
  • 便于操作:通过三元组表示法,可以方便地进行矩阵的各种操作,如转置、加法等。

缺点

  • 插入和删除操作复杂:如果需要插入或删除非零元素,需要对三元组顺序表进行移动和调整,操作比较复杂。
  • 不适合随机访问:由于三元组顺序表是按一定顺序存储的,不适合随机访问矩阵中的元素。

总结

稀疏矩阵的三元组表示法是数据结构课程中的一个重要内容,它通过只存储非零元素的方式,有效地节省了存储空间。

http://www.xdnf.cn/news/8587.html

相关文章:

  • 23种设计模式全面解析
  • 告别Feign:基于Spring 6.1 RestClient构建高可靠声明式HTTP客户端
  • 今日多肽之——订书肽
  • Linux文件类型
  • 建筑科技的未来图景:探究中建海龙的创新基因
  • C语言超详细结构体知识
  • 工程化实践:Flutter项目结构与规范
  • 广东中级消防设施操作员理论考试精选题
  • SpringAI+DeepSeek大模型应用开发——5 ChatPDF
  • 相比其他缓存/内存数据库(如 Memcached, Ehcache 等),Redis 在微服务环境中的优势和劣势是什么?
  • 【RK3588 嵌入式图形编程】-SDL2-扫雷游戏-结束和重新开始游戏
  • string函数的应用
  • Python 写生成 应用商店(2025版) 网页 方便收集应用 ,局域网使用
  • 极狐GitLab 外部授权控制机制是怎样的?
  • 【前端知识】今天聊一聊web的事件机制
  • SpringBoot学习(properties、yml(主流)、yaml格式配置文件)(读取yml配置文件的3种方式)(详解)
  • Kafka消费者端重平衡流程
  • 中间件--ClickHouse-9--MPP架构(分布式计算架构)
  • kafka菜鸟教程
  • GEE学习笔记 29:基于GEE的多源Landsat合成与植被指数时序提取
  • axios 模拟实现
  • 【HFP】蓝牙HFP协议音频连接核心技术深度解析
  • 【2】CICD持续集成-k8s集群中安装Jenkins
  • 8.观察者模式:思考与解读
  • 【SAP ME 44】在 HANA DB中报废SFC时的SHOP_ORDER表记录锁定
  • 设计模式从入门到精通之(五)观察者模式
  • LIB-ZC, 一个跨平台(Linux)平台通用C/C++扩展库, stream 流操作
  • conversation_template | conversation_actors | conversation_line_template
  • 网安加·百家讲坛 | 刘志诚:AI安全风险与未来展望
  • MCP的推出将给未来的开发带来哪些变革?