特殊矩陣的壓縮存儲(下)

概述:主要是實現稀疏矩陣的三元組存儲和十字鏈表存儲

稀疏矩陣:稀疏矩陣是指矩陣中非零元素個數遠遠小於矩陣元素總數,且分佈沒有規律的矩陣。

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);
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章