数据结构之——稀疏矩阵
来源:互联网 发布:医学数据可视化ppt 编辑:程序博客网 时间:2024/06/04 18:54
稀疏矩阵
在矩阵中,若数值为0的元素数目远远多于非0元素的数目时,则称该矩阵为稀疏矩阵。我们使用三元组来存放非零元素,row为横坐标,column为纵坐标,value为值。
本篇介绍的是稀疏矩阵的数据结构、普通转置、快速转置的方法。
三元组节点
//节点class TripleNode { public int row;// 行号 public int column;// 列号 public int value;// 值 public TripleNode() { this(0, 0, 0); } public TripleNode(int row, int column, int value) { this.row = row; this.column = column; this.value = value; }}
稀疏矩阵转化为三元组
基本思想是:首先计算矩阵中非零元素的个数,然后创建三元组数组,循环遍历整个矩阵,分别把非零元素的横坐标,纵坐标,值放入三元组的节点。
// 将稀疏矩阵变为三元组 public SparesMatrix(int[][] mat) { rows = mat.length; cols = mat[0].length; // 计算非零元素的个数 for (int i = 0; i < rows; i++) { for (int j = 0; j < mat[i].length; j++) { if (mat[i][j] != 0) { nums++; } } } int k = 0; data = new TripleNode[nums]; for (int i = 0; i < mat.length; i++) { for (int j = 0; j < mat[i].length; j++) { if (mat[i][j] != 0) { data[k] = new TripleNode(i, j, mat[i][j]); k++;// 由于非零元素个数已知,所以不会越界 } } } }
普通转置
如图,我们可以看到,转置就是横坐标与纵坐标进行互换。
普通转置的基本思想:创建一个三元组,对原三元组进行遍历,从列为0开始在原三元组中找到最小列的非零元素,存入转置三元组。
这个算法的复杂度为 O(n*t)
n为矩阵的列数,t为三元组中非零元素个数。
// 普通转置 public SparesMatrix transpose() { SparesMatrix tmMatrix = new SparesMatrix(nums); tmMatrix.cols = rows; tmMatrix.rows = cols; tmMatrix.nums = nums; int q = 0; // 转置并按先行后列排序 for (int col = 0; col < cols; col++) { for (int p = 0; p < nums; p++) { if (data[p].column == col) {// 遍历整个三元组从最小的列开始寻找,原来的三元组已经是排序好的,只需要按照列最小寻找就好 tmMatrix.data[q].column = data[p].row; tmMatrix.data[q].row = data[p].column; tmMatrix.data[q].value = data[p].value; q++; } } } return tmMatrix; }
快速转置
基本思想:由于转置时,列变成了行,所以我们从每列出发,寻找每列中第一个非零元素,并在转置三元组中计算它的位置。最后遍历原三元组,来完成转置三元组。
算法复杂度为 O(n+t),n为矩阵的列,t为非零元素个数。
例如:我们先找到第0列的第一个非零元素,它在转置三元组中的位置为0,计算这个列中共有2个非零元素,那么寻找到第二列的第一个非零元素时,它在转置三元组的位置就是0+2=2
这里使用到了两个数组:
num[x] , x表示列,值表示非零元素个数
cpot[x] , x表示列,值表示该列非零元素在转置三元组的位置
必须要读num进行初始化,其每个值表示每列的非零个数,0则表示该列全为0,无非零元素。
// 对num[]初始化 for (int i = 0; i < cols; i++) { num[i] = 0; }
默认cpot[0]=0,如果第0列不存在非零元素,会被覆盖,即
cpot[1] = cpot[0] + num[0] = 0
cpot[1] = 0
cpot[0] = 0; // 计算位置 for (int i = 1; i < cols; i++) { cpot[i] = cpot[i - 1] + num[i - 1];// 每列第一个非零元素在转置三元组的位置 }
// 快速转置 public SparesMatrix fasttanspose() { SparesMatrix tMatrix = new SparesMatrix(nums); tMatrix.rows = cols; tMatrix.cols = rows; tMatrix.nums = nums; int[] num = null;// 每列非零元素的个数,下标表示列,值表示元素个数 int[] cpot = null;// 每列首个非零元素在转置三元组的位置,下标表示列,值表示位置 // 初始化 if (nums > 0) { num = new int[cols]; cpot = new int[cols]; } // 对num[]初始化 for (int i = 0; i < cols; i++) { num[i] = 0; } int j = 0; // 计算每列非零元素的个数 for (int i = 0; i < nums; i++) { j = data[i].column; num[j]++; // 同一列有非零元素,值加1 } cpot[0] = 0; // 计算位置 for (int i = 1; i < cols; i++) { cpot[i] = cpot[i - 1] + num[i - 1];// 每列第一个非零元素在转置三元组的位置 } j = 0; int k = 0; // 对原三元组进行相应的转换 for (int i = 0; i < nums; i++) {// 对原三元组进行遍历 j = data[i].column; k = cpot[j];// 转置三元组中的位置 tMatrix.data[k].column = data[i].row; tMatrix.data[k].row = data[i].column; tMatrix.data[k].value = data[i].value; cpot[j]++;// 同列下一个非零元素的位置 } return tMatrix; }
完整代码
//节点class TripleNode { public int row;// 行号 public int column;// 列号 public int value;// 值 public TripleNode() { this(0, 0, 0); } public TripleNode(int row, int column, int value) { this.row = row; this.column = column; this.value = value; }}// 稀疏矩阵public class SparesMatrix { public TripleNode[] data;// 三元组 public int cols;// 整个矩阵的列数 public int rows;// 整个矩阵的行数 public int nums;// 非零元素个数 // 分配三元组的存储空间 public SparesMatrix(int maxSize) { data = new TripleNode[maxSize]; //要对每个data[] 初始化 for (int i = 0; i < maxSize; i++) { data[i] = new TripleNode(); } rows = 0; cols = 0; nums = 0; } public SparesMatrix() { } // 将稀疏矩阵变为三元组 public SparesMatrix(int[][] mat) { rows = mat.length; cols = mat[0].length; // 计算非零元素的个数 for (int i = 0; i < rows; i++) { for (int j = 0; j < mat[i].length; j++) { if (mat[i][j] != 0) { nums++; } } } int k = 0; data = new TripleNode[nums]; for (int i = 0; i < mat.length; i++) { for (int j = 0; j < mat[i].length; j++) { if (mat[i][j] != 0) { data[k] = new TripleNode(i, j, mat[i][j]); k++;// 由于非零元素个数已知,所以不会越界 } } } } // 打印 public void display() { System.out.println("Matrix's rows is " + rows + "\t" + "colmns is " + cols); System.out.println("rows" + "\t" + "colmns" + "\t" + "values"); for (int i = 0; i < data.length; i++) { System.out.println(data[i].row + "\t" + data[i].column + "\t" + data[i].value); } } // 普通转置 public SparesMatrix transpose() { SparesMatrix tmMatrix = new SparesMatrix(nums); tmMatrix.cols = rows; tmMatrix.rows = cols; tmMatrix.nums = nums; int q = 0; // 转置并按先行后列排序 for (int col = 0; col < cols; col++) { for (int p = 0; p < nums; p++) { if (data[p].column == col) {// 遍历整个三元组从最小的列开始寻找,原来的三元组已经是排序好的,只需要按照列最小寻找就好 tmMatrix.data[q].column = data[p].row; tmMatrix.data[q].row = data[p].column; tmMatrix.data[q].value = data[p].value; q++; } } } return tmMatrix; } // 快速转置 public SparesMatrix fasttanspose() { SparesMatrix tMatrix = new SparesMatrix(nums); tMatrix.rows = cols; tMatrix.cols = rows; tMatrix.nums = nums; int[] num = null;// 每列非零元素的个数,下标表示列,值表示元素个数 int[] cpot = null;// 每列首个非零元素在转置三元组的位置,下标表示列,值表示位置 // 初始化 if (nums > 0) { num = new int[cols]; cpot = new int[cols]; } // 对num[]初始化 for (int i = 0; i < cols; i++) { num[i] = 0; } int j = 0; // 计算每列非零元素的个数 for (int i = 0; i < nums; i++) { j = data[i].column; num[j]++; // 同一列有非零元素,值加1 } cpot[0] = 0; // 计算位置 for (int i = 1; i < cols; i++) { cpot[i] = cpot[i - 1] + num[i - 1];// 每列第一个非零元素在转置三元组的位置 } j = 0; int k = 0; // 对原三元组进行相应的转换 for (int i = 0; i < nums; i++) {// 对原三元组进行遍历 j = data[i].column; k = cpot[j];// 转置三元组中的位置 tMatrix.data[k].column = data[i].row; tMatrix.data[k].row = data[i].column; tMatrix.data[k].value = data[i].value; cpot[j]++;// 同列下一个非零元素的位置 } return tMatrix; } public static void main(String[] args) { int mat[][] = { { 0, 0, 8, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0 }, { 5, 0, 0, 0, 16, 0 }, { 0, 0, 18, 0, 0, 0 }, { 0, 0, 0, 9, 0, 0 } }; SparesMatrix sMatrix = new SparesMatrix(mat); sMatrix.display(); System.out.println(); sMatrix.transpose().display(); System.out.println(); sMatrix.fasttanspose().display(); }}
结果显示:
Matrix's rows is 5 colmns is 6rows colmns values0 2 82 0 52 4 163 2 184 3 9Matrix's rows is 6 colmns is 5rows colmns values0 2 52 0 82 3 183 4 94 2 16Matrix's rows is 6 colmns is 5rows colmns values0 2 52 0 82 3 183 4 94 2 16
阅读全文
1 0
- 数据结构之——稀疏矩阵
- 数据结构——稀疏矩阵
- 稀疏矩阵——数据结构
- 数据结构之稀疏矩阵
- 数据结构之稀疏矩阵
- 数据结构之 矩阵---稀疏矩阵
- 经典数据结构之稀疏矩阵
- 数据结构实验10——稀疏矩阵
- 数据结构实践——稀疏矩阵相加
- 数据结构之自建算法库——稀疏矩阵的三元组表示
- 数据结构之自建算法库——稀疏矩阵的三元组表示
- 数据结构之稀疏矩阵17简要介绍
- 数据结构之---C语言实现稀疏矩阵
- 算法与数据结构之稀疏矩阵
- 数据结构实验之数组二:稀疏矩阵
- 数据结构实验之数组二:稀疏矩阵
- 数据结构实验之数组二:稀疏矩阵
- 数据结构实验之数组二:稀疏矩阵
- 为什么 Git 比 SVN 好
- TCP中的常见定时器及TIME-WAIT原理
- python3 字符串方法
- 基本css,网站开发问题
- void及void指针含义的深刻解析
- 数据结构之——稀疏矩阵
- 2017年6月26日
- hdu 5122 K.Bro Sorting(思维+冒泡思想)
- Java中String和byte[]转换(包括十六进制转换)
- 轮盘抽奖
- nginx 1.4.6 设置上传大小 client_max_body_size
- Spring的注解@Qualifier小总结
- 彻底删除Oracle 11g的方法
- HybridDB for MySQL 实现在线与离线数据分离的实践