当前位置: 首页 > 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

三元组表示法的优缺点

优点

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

缺点

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

总结

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

相关文章:

  • 树莓派超全系列教程文档--(31)config.txt常用选项介绍
  • 游戏一:俄罗斯方块简易版
  • vue3+element-ui-plus+el-table样式
  • 基于WebRTC技术的EasyRTC:支持任意平台设备的实时音视频通信解决方案
  • git本地项目上传github
  • 数字图像处理(膨胀与腐蚀)
  • 如何模拟浏览器行为获取网页中的隐藏表单数据?
  • 5.0.2 颜色16进制格式含义 控件template中path的使用
  • Oracle AWR快照保留策略及其修改
  • 通过特定协议拉起 electron 应用
  • 今日多肽之——订书肽
  • Linux网络通信核心机制解析与层级架构探秘
  • J值即正义——Policy Gradient思想、REINFORCE算法,以及贪吃蛇小游戏(三)
  • 迭代器模式:统一不同数据结构的遍历方式
  • 完美解决浏览器不能复制的问题(比如赛氪网的中题库练习题)
  • Spring 数据库编程
  • Redis(二) - Redis命令详解
  • Java 使用 LangChain4j 搭建大模型的 RAG 教程
  • sort和swap函数
  • MODBUS TCP 转 CANOpen
  • 男子为讨喜钱掰断劳斯莱斯小金人,警方:已介入处置
  • 锚定“水库不垮坝”目标,水利部部署今年水库安全度汛工作
  • 中纪委驻中组部纪检监察组原组长李刚被捕
  • 人民日报刊文:美国滥施关税及中国反制措施的法理视角透析
  • 外交部:中企在中韩暂定水域建立渔业养殖设施不违反中韩有关协定
  • 美方因涉港问题对中国官员滥施非法单边制裁,外交部:强烈谴责,对等反制