概述:主要是實現稀疏矩陣的三元組存儲和十字鏈表存儲
稀疏矩陣:稀疏矩陣是指矩陣中非零元素個數遠遠小於矩陣元素總數,且分佈沒有規律的矩陣。
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);
}
}