矩阵的压缩存储

一、矩阵的分类

1、特殊矩阵:其矩阵值在在矩阵中分布有规律
2、稀疏矩阵:矩阵的非零值在矩阵中占比小于0.05的矩阵,即零值占比在95%以上
3、一般矩阵:不属于上面的两种矩阵

二、矩阵的存储方式

1、特殊矩阵的存储方式

1、特殊矩阵包括三角矩阵,带状矩阵 都是使用顺序存储

2、稀疏矩阵的存储方式

稀疏矩阵的存储方式有两种,其一:三元组顺序表(顺序存储)其二:十字链表(链式存储)

1、稀疏矩阵的三元组顺序表存储

3矩阵的转置

1、一般矩阵转置

2、 稀疏矩阵的一般转置

3、稀疏矩阵的快速排序

假如我们直接知道转置前的三元组数组的每个元素在转置后的三元组数组中位置,我们就可以直接转了
要想知道转置后的位置,我们必须要总结转置前的三元组数组的更详细信息。
由于转置后行列互换,所以转置后的三元组数组是按照行顺序记录的,所以我们要知道转置前矩阵的每列元素个数mun(j),另外我们还需要知道转置前的矩阵的每一列元素的第一个非0元素在转置后的三元组数组中的位置Pos(j)
那么我们就可以根据mun(j)和Pos(j)来确定转置前的三元组数组的每个元素在转置后的三元组数组中位置
计算方法

代码

//稀疏矩阵的三元组顺序表存储表示.cpp #include<malloc.h> // malloc()等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()
// 函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1// #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE
typedef int ElemType;#define MAX_SIZE 100 // 非零元个数的最大值
struct Triple
{int i, j; // 行下标,列下标ElemType e; // 非零元素值
};
struct TSMatrix
{Triple data[MAX_SIZE + 1]; // 非零元三元组表,data[0]未用int mu, nu, tu; // 矩阵的行数、列数和非零元个数
};// 1、创建稀疏矩阵M
Status CreateSMatrix(TSMatrix &M);
// 2、输出稀疏矩阵M
void PrintSMatrix(TSMatrix M);
//3、输出完整的矩阵
void display(TSMatrix M);
//4、输出完整的矩阵
void PrintSMatrix1(TSMatrix M);
//5、复制矩阵T = M
void CopySMatrix(TSMatrix M, TSMatrix &T);
//6、求稀疏矩阵的和Q=M+N
Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q);
//7、求稀疏矩阵的差Q=M-N
Status SubtSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q);
//8、 求稀疏矩阵M的转置矩阵T,普通方法
void TransposeSMatrix(TSMatrix M, TSMatrix &T);int main() { TSMatrix M;CreateSMatrix(M);PrintSMatrix(M);display(M);
}//1、创建稀疏矩阵M
Status CreateSMatrix(TSMatrix &M)
{ int i, m, n;ElemType e;Status k;printf("请输入矩阵的行数,列数,非零元素数:");scanf_s("%d, %d, %d", &M.mu, &M.nu, &M.tu);if (M.tu > MAX_SIZE)return ERROR;M.data[0].i = 0; // 为以下比较顺序做准备for (i = 1; i <= M.tu; i++){do{printf("请按行序顺序输入第%d个非零元素所在的行(1~%d),列(1~%d),元素值:", i, M.mu, M.nu);scanf_s("%d,%d,%d", &m, &n, &e);k = 0;if (m<1 || m>M.mu || n<1 || n>M.nu) // 行或列超出范围k = 1;if (m < M.data[i - 1].i || m == M.data[i - 1].i&&n <= M.data[i - 1].j) // 行或列的顺序有错,M.data[i - 1].i当前输入数据的前一个数据的行坐标 M.data[i - 1].j当前输入数据的前一个数据的列坐标k = 1;} while (k);//输入值的行列不按顺序输入则重新输入M.data[i].i = m;M.data[i].j = n;M.data[i].e = e;}return OK;
}
//2、输出稀疏矩阵M的非0值
void PrintSMatrix(TSMatrix M)
{ int i;printf("%d行%d列%d个非零元素。\n", M.mu, M.nu, M.tu);printf("行  列  元素值\n");for (i = 1; i <= M.tu; i++)//按顺序输出数组中的值printf("%2d%4d%8d\n", M.data[i].i, M.data[i].j, M.data[i].e);
}
//3、输出完整的矩阵
void display(TSMatrix M)
{for (int i = 1; i <= M.mu; i++) {//循环行for (int j = 1; j <= M.nu; j++) {//循环列int value = 0;//标志变量for (int k = 0; k <= M.tu; k++) {//循环非0值if (i == M.data[k].i && j == M.data[k].j) {//行和列等于非0值的行和列时打印非0值不等则打印0值printf("%d ", M.data[k].e);value = 1;break;}}if (value == 0)printf("0 ");}printf("\n");}
}
//4、输出完整的矩阵
void PrintSMatrix1(TSMatrix M)
{ // 按矩阵形式输出Mint i, j, k = 1;Triple *p = M.data;p++; // p指向第1个非零元素for (i = 1; i <= M.mu; i++)//循环行{for (j = 1; j <= M.nu; j++)//循环列if (k <= M.tu&&p->i == i && p->j == j) // p指向非零元,且p所指元素为当前处理元素{printf("%3d", p->e); // 输出p所指元素的值p++; // p指向下一个元素k++; // 计数器+1}else // p所指元素不是当前处理元素printf("%3d", 0); // 输出0printf("\n");}
}
//5、复制矩阵T = M
void CopySMatrix(TSMatrix M, TSMatrix &T)
{ // 由稀疏矩阵M复制得到TT = M;
}int comp(int c1, int c2)
{ // AddSMatrix函数要用到,另加if (c1 < c2)return -1;if (c1 == c2)return 0;return 1;
}
//6、求稀疏矩阵的和Q=M+N
Status AddSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)
{  int m = 1, n = 1, q = 0;if (M.mu != N.mu || M.nu != N.nu) // M、N两稀疏矩阵行或列数不同return ERROR;Q.mu = M.mu;Q.nu = M.nu;while (m <= M.tu&&n <= N.tu) // 矩阵M和N的元素都没处理完{switch (comp(M.data[m].i, N.data[n].i)){case -1: Q.data[++q] = M.data[m++]; // 将矩阵M的当前元素值赋给矩阵Qbreak;case  0: switch (comp(M.data[m].j, N.data[n].j)) // M、N矩阵当前元素的行相等,继续比较列{case -1: Q.data[++q] = M.data[m++];break;case  0: Q.data[++q] = M.data[m++]; // M、N矩阵当前非零元素的行列均相等Q.data[q].e += N.data[n++].e; // 矩阵M、N的当前元素值求和并赋给矩阵Qif (Q.data[q].e == 0) // 元素值为0,不存入压缩矩阵q--;break;case  1: Q.data[++q] = N.data[n++];}break;case  1: Q.data[++q] = N.data[n++]; // 将矩阵N的当前元素值赋给矩阵Q}}while (m <= M.tu) // 矩阵N的元素全部处理完毕Q.data[++q] = M.data[m++];while (n <= N.tu) // 矩阵M的元素全部处理完毕Q.data[++q] = N.data[n++];Q.tu = q; // 矩阵Q的非零元素个数if (q > MAX_SIZE) // 非零元素个数太多return ERROR;return OK;
}
//7、求稀疏矩阵的差Q=M-N
Status SubtSMatrix(TSMatrix M, TSMatrix N, TSMatrix &Q)
{ int i;for (i = 1; i <= N.tu; i++)N.data[i].e *= -1;return AddSMatrix(M, N, Q);
}
//8、 求稀疏矩阵M的转置矩阵T,普通方法
void TransposeSMatrix(TSMatrix M, TSMatrix &T)
{ int p, q, col;T.mu = M.nu;T.nu = M.mu;T.tu = M.tu;if (T.tu){q = 1;for (col = 1; col <= M.nu; ++col)//依次给出列标1-M.nufor (p = 1; p <= M.tu; ++p)//循环非0元素if (M.data[p].j == col)//如果M的第p个三元组的列元素和循环的列标相等,则转置非零元素{T.data[q].i = M.data[p].j;T.data[q].j = M.data[p].i;T.data[q].e = M.data[p].e;++q;//计数器+1}}
}

数据结构笔记(十七)--矩阵的压缩存储相关推荐

  1. 数据结构的学习_4.2 矩阵的压缩存储(对称矩阵)

    4.2 矩阵的压缩存储(一) 在有些情况下,矩阵中含有许多值相同或者值为零的元素,如果还按前面的方法来存储这种矩阵,就会产生大量的空间浪费.为了节省存储空间,可以对这类矩阵采用压缩存储. 4.2.1 ...

  2. 数据结构C语言实现-矩阵的压缩存储

    一.矩阵的压缩存储: 在编写程序时往往都是二维数组表示矩阵,然而在数值分析中经常出现一些阶数很高的的矩阵同时在距震中有很多值相同的元素,或者是零元素,为了节省空间,可以对这类矩阵进行压缩存储,所谓的压 ...

  3. 矩阵的压缩存储(随机稀疏矩阵的建立和输出)

    实际应用中会有很多利用高阶矩阵的问题,有的高阶矩阵已达到几十万阶,几千亿个元素.然而,多数的高阶矩阵中包含了大量的数值为零的元素,需要对这类矩阵进行压缩存储.因为合理的压缩存储不仅能有效地节省存储空间 ...

  4. 5.3矩阵的压缩存储(稀疏矩阵转置和快速转置)

    在矩阵中有许多值相同的元素或者是零元素.有时为了节省存储空间,可以对这类矩阵进行压缩存储.所谓的压缩存储是指:为多个值相同的元值分配一个存储空间:对零元不分配空间. 5.32稀疏矩阵 在m*n的矩阵中 ...

  5. 9.特殊矩阵的压缩存储

    压缩存储:指多个值相同的元素只分配一个存储空间, 对零元素不分配存储空间. 特殊矩阵:指具有许多相同矩阵元素或零元素,并且这些相同矩阵元素或零元素的 分布有一定规律性的矩阵. 特殊矩阵的压缩存储:找出 ...

  6. 34-对称矩阵的压缩存储

    对于矩阵这样由n行n列构成的数据集合,可以通过二维数组来进行存储. 在实际工程中也会用到一些特殊的矩阵, 特殊矩阵可以"压缩"的一种思维来降低空间需求. (1)对角矩阵 (2)对称 ...

  7. 特殊矩阵的压缩存储(对称矩阵,三角矩阵,对角矩阵,稀疏矩阵的顺序,链序存储,十字链表的建立)

    特殊矩阵的压缩存储 压缩存储的定义: 若多个数据元素的值都相同,则只分配一个元素值的存储空间,且 零元素不占存储空间. 能够压缩的一些矩阵: 一些特殊矩阵,如:对称矩阵,对角矩阵,三角矩阵,稀疏矩阵等 ...

  8. 特殊矩阵的压缩存储(详细版 通俗易懂 含c语言稀疏矩阵十字链表代码 )

    前言 此文章是本人第一篇博客,目的在于巩固过去所学的知识,同时可能会给大家带来一丝丝帮助,但由于没有经验加上本人能力极其有限,文章中可能存在不足之处,还请读者能够指正(`・ω・´). 这篇文章首先会介 ...

  9. 3~4矩阵的压缩存储(下)【详解】

    目录 一.特殊矩阵的压缩存储 1.数组的定义 1.1概述 1.2数组与线性表的关系 1.3特点 2.数组的存储结构 2.1一个数组 2.2多维数组 二.矩阵的压缩存储 1.概述 1.1压缩存储 1.2 ...

最新文章

  1. html里的swal添加倒计时,使用甜蜜警报插件的setInterval函数倒计时
  2. Math类(工具类)
  3. 一个完整的Core Data应用
  4. Ubuntu通过apt-get安装指定版本和查询指定软件有多少个版本
  5. 使用国内源安装k8s
  6. linux内存实验,LINUX编程-实验五 内存管理实验
  7. JVM: G1和CMS的区别
  8. boost::math模块使用 agm 以高精度计算 lemniscate 常量
  9. 贪心算法两船装载问题Java_贪心算法-最优装载问题
  10. 数据库设计14个技巧
  11. JAVA调用 keras,在TensorFlow(Python, Java)环境下使用Keras模型
  12. c++ 数字后加f_Pandas 实战系列:数字格式设置
  13. 兰州大学c语言课程作业答案,2016兰州大学C语言程序设计课程作业1附答案.doc
  14. 面向深度学习研究人员的自然语言处理实例教程
  15. 剑指offer 数字在排序数组中出现的次数
  16. 家谱处理 (30 分)(map映射)
  17. Jenkins+Spring Boot构建部署
  18. TensorFlow by Google 实战CNN Machine Learning Foundations: Ep #4 - Coding with CNN
  19. 关于O、Θ、Ω、o、ω等数学符号
  20. H3C路由器多出口NQA+TRACK实现冗余

热门文章

  1. 2017 Multi-University Training Contest - Team 7:1010. Just do it(组合数?)
  2. bzoj 1005: [HNOI2008]明明的烦恼(prufer数列)
  3. python命令行解析库——argparse库的使用
  4. python批量更改图片尺寸(保持长度和高度的长短关系)
  5. quartus仿真27:JK触发器构成的同步二进制加法计数器(分析)
  6. Mysql中外键的 Cascade ,NO ACTION ,Restrict ,SET NULL
  7. 4种操作符的区别和联系
  8. 【 VS 插件开发 】三、Vs插件简单功能的实现
  9. Leetcode Trie Conclusion
  10. 生成XML文件的步骤 解析XML文件