-
简介
稀疏矩阵是矩阵中的非零元素个数远远少于零元素个数。
一般会通过稀疏因子来进行确定。假设在m×n的矩阵中,有t个元素不为0.令∂=t÷(m×n).若∂<=0.05时称为稀疏矩阵。
稀疏矩阵通过三元组进行存储
三元组结构
private class Node {
//列数
int x;
//行数
int y;
//元素
int elem;
public Node(int x, int y, int elem) {
this.x = x;
this.y = y;
this.elem = elem;
}
}
-
Java代码实现
/**
* 稀疏矩阵
*/
public class SparseMatrix {
//记录列数
private int col;
//记录行数
private int row;
//三元组存储矩阵
private List compression;
//三元组
private class Node {
//列数
int x;
//行数
int y;
//元素
int elem;
public Node(int x, int y, int elem) {
this.x = x;
this.y = y;
this.elem = elem;
}
}
/**
* 三元组压缩稀疏矩阵。
* 从左往右,从下往上的顺序压缩。
* @param target 待压缩的稀疏矩阵
* @return 当前对象
*/
SparseMatrix compression(int[][] target) {
if (target == null) {
throw new UnsupportedOperationException("不支持Null");
}
col = target[0].length;
row = target.length;
compression = new ArrayList<>();
for (int y = 0; y < row; y++) {
for (int x = 0; x < col; x++) {
if (target[y][x] != 0) {
compression.add(new Node(x, y, target[y][x]));
}
}
}
return this;
}
/**
* 三元组打印矩阵
* @return 当前对象
*/
SparseMatrix printMatrix() {
if (compression == null) {
throw new UnsupportedOperationException("未初始化");
}
Node node = null;
int index = 0;
if (index < compression.size()) {
node = compression.get(index++);
}
for (int y = 0; y < row; y++) {
for (int x = 0; x < col; x++) {
if (node != null && node.x == x && node.y == y) {
System.out.print(node.elem + "\t");
node = index < compression.size() ? compression.get(index++) : null;
} else {
System.out.print("0\t");
}
}
System.out.println();
}
System.out.println();
return this;
}
/**
* 线性打印三元组
* @return 当前对象
*/
SparseMatrix printLinear() {
if (compression == null) {
throw new UnsupportedOperationException("未初始化");
}
for (Node node : compression) {
System.out.print(node.elem + "\t");
}
System.out.println();
return this;
}
/**
* 暴力转置矩阵
* @return
*/
SparseMatrix forceRotateMatrix() {
if (compression == null) {
throw new UnsupportedOperationException("未初始化");
}
List rotate = new ArrayList<>(compression.size());
int temp = col;
col = row;
row = temp;
int y = 0;
//搜索列
while (y < row) {
for (Node node : compression) {
//X和Y交换
if (node.x == y) {
rotate.add(new Node(node.y, node.x, node.elem));
}
}
y++;
}
compression = rotate;
return this;
}
/**
* 快速转置三元组
* @return
*/
SparseMatrix quickRotateMatrix() {
if (compression == null) {
throw new UnsupportedOperationException("未初始化");
}
//记录旋转后每行的个数,也就是当前每列的个数
int[] location = new int[col];
for (Node node : compression) {
location[node.x]++;
}
//计算列第一个非0元素的开始位置
int[] begin = new int[col];
for (int i = 1; i < location.length; i++) {
begin[i] = begin[i - 1] + location[i];
}
//推算索引位置
int[] back = location.clone();
//ArrayList不支持插入任意位置
Node[] rotate = new Node[compression.size()];
int offset;
for (Node node : compression) {
offset = location[node.x] - back[node.x]--;
// System.out.println("偏移量:" + offset);
// System.out.println("位置:" + (begin[node.x] + offset));
rotate[begin[node.x] + offset] = new Node(node.y, node.x, node.elem);
}
int temp = col;
col = row;
row = temp;
compression = Arrays.asList(rotate);
return this;
}
}
-
测试
int[][] target = {
{0, 12, 9, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0},
{-3, 0, 0, 0, 0, 14, 0},
{0, 0, 24, 0, 0, 0, 0},
{0, 18, 0, 0, 0, 0, 0},
{15, 0, 0, -7, 0, 0, 0}
};
SparseMatrix sparseMatrix = new SparseMatrix();
sparseMatrix.compression(target).printMatrix().forceRotateMatrix().printMatrix().quickRotateMatrix().printMatrix();
打印结果
0 12 9 0 0 0 0
0 0 0 0 0 0 0
-3 0 0 0 0 14 0
0 0 24 0 0 0 0
0 18 0 0 0 0 0
15 0 0 -7 0 0 0
0 0 -3 0 0 15
12 0 0 0 18 0
9 0 0 24 0 0
0 0 0 0 0 -7
0 0 0 0 0 0
0 0 14 0 0 0
0 0 0 0 0 0
0 12 9 0 0 0 0
0 0 0 0 0 0 0
-3 0 0 0 0 14 0
0 0 0 0 0 0 0
0 18 0 0 0 0 0
0 0 0 0 0 0 0