概述:主要是实现稀疏矩阵的三元组存储和十字链表存储
稀疏矩阵:稀疏矩阵是指矩阵中非零元素个数远远小于矩阵元素总数,且分布没有规律的矩阵。
a.三元组存储
三元组的存储原则是指存储非零元素,包括元素的位置和值。
b.十字矩阵存储
当稀疏矩阵的元素个数和位置经常发生变化时,不宜采用三元组存储,应该采用链式存储,在十字链表中,除了存储结点本身的信息(位置、值),还存储了指向当前行的下一个非零元素的指针(right域)和当前列的下一个非零元素的指针(down域)
从十字链表的定义中可以发现,至少需要一个数组存储每一行或者每一列的头节点。
实现:
三元组节点类:
public class TripleNode {
private int row; // 行
private int col; // 列
private int value; // 值
public TripleNode() {
this(0, 0, 0);
}
public TripleNode(int row, int col, int value) {
this.row = row;
this.col = col;
this.value = value;
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
十字矩阵节点类:
public class OLNode {
private int row;
private int col;
private int value;
private OLNode right;
private OLNode down;
public OLNode(int row, int col, int value) {
super();
this.row = row;
this.col = col;
this.value = value;
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public OLNode getRight() {
return right;
}
public void setRight(OLNode right) {
this.right = right;
}
public OLNode getDown() {
return down;
}
public void setDown(OLNode down) {
this.down = down;
}
}
十字链表中用于返回行和列头节点数组的类:
public class RowAndColHeadNode {
private OLNode[] rowHead;
private OLNode[] colHead;
public RowAndColHeadNode(OLNode[] rowHead, OLNode[] colHead) {
super();
this.rowHead = rowHead;
this.colHead = colHead;
}
public OLNode[] getRowHead() {
return rowHead;
}
public void setRowHead(OLNode[] rowHead) {
this.rowHead = rowHead;
}
public OLNode[] getColHead() {
return colHead;
}
public void setColHead(OLNode[] colHead) {
this.colHead = colHead;
}
}
获取三元组和十字链表的类:
public class Matrix {
private int rows;
private int cols;
private int values;
private OLNode[] rowHead;
private OLNode[] colHead;
public Matrix() {
rows = 0;
cols = 0;
values = 0;
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getCols() {
return cols;
}
public void setCols(int cols) {
this.cols = cols;
}
public int getValues() {
return values;
}
public void setValues(int values) {
this.values = values;
}
public OLNode[] getRowHead() {
return rowHead;
}
public void setRowHead(OLNode[] rowHead) {
this.rowHead = rowHead;
}
public OLNode[] getColHead() {
return colHead;
}
public void setColHead(OLNode[] colHead) {
this.colHead = colHead;
}
/**
* 根据入参的稀疏矩阵输出对应的三元组
*
* @param mat
* 稀疏矩阵
* @return 三元组
*/
public TripleNode[] getTripleArray(int[][] mat) {
setParam(mat);
TripleNode[] tripleNode = new TripleNode[values];
int k = 0;
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
if (mat[i][j] != 0) {
tripleNode[k] = new TripleNode(i, j, mat[i][j]);
k++;
}
}
}
return tripleNode;
}
/**
* 设置总行数和非零元素总数
*
* @param mat
* 稀疏矩阵
*/
private void setParam(int[][] mat) {
for (int[] i : mat) {
for (int j : i) {
if (j != 0) {
values++;
}
}
}
rows = mat.length;
cols = mat[0].length;
}
/**
* 初始化头节点数组
*/
private void initHeadNodeArray() {
rowHead = new OLNode[rows];
colHead = new OLNode[cols];
// 初始化行头节点数组
for (int i = 0; i < rows; i++) {
rowHead[i] = new OLNode(i, -1, 0);
}
// 初始化列头节点数组
for (int i = 0; i < cols; i++) {
colHead[i] = new OLNode(-1, i, 0);
}
}
/**
* 插入节点
*
* @param row
* 行号
* @param col
* 列号
* @param value
* 节点值
*/
private void insertNode(int row, int col, int value) {
OLNode node = new OLNode(row, col, value);
OLNode pRow = rowHead[row];
OLNode pCol = colHead[col];
// 设置横向的链表
while (pRow.getRight() != null) {
pRow = pRow.getRight();
}
pRow.setRight(node);
// 设置纵向的链表
while (pCol.getDown() != null) {
pCol = pCol.getDown();
}
pCol.setDown(node);
}
/**
* 根据入参的稀疏矩阵输出对应的十字链表
*
* @param mat
* 稀疏矩阵
* @return 十字链表
*/
public RowAndColHeadNode getCrossList(int[][] mat) {
setParam(mat);
initHeadNodeArray();
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
if (mat[i][j] != 0) {
insertNode(i, j, mat[i][j]);
}
}
}
return new RowAndColHeadNode(rowHead, colHead);
}
}