特殊矩阵的压缩存储(下)

概述:主要是实现稀疏矩阵的三元组存储和十字链表存储

稀疏矩阵:稀疏矩阵是指矩阵中非零元素个数远远小于矩阵元素总数,且分布没有规律的矩阵。

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

 

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