稀疏矩阵的转置

稀疏矩阵的转置

​ 设带转置矩阵 A 的列为 col,共有 num 个元素,

​ 使用了两种方法进行转置,一种时间复杂度是 O(col* num),一种时间复杂度是O(max(col, num))

//矩阵中的元素
class Item {
    int row;
    int col;
    int item;

    public Item(int row, int col, int item) {
        this.row = row;
        this.col = col;
        this.item = item;
    }
}

//系数矩阵的定义
class SparseMatrix {
    Item[] elements;
    int num;    //元素个数
    public SparseMatrix(int num) {
        this.num = num;
        elements = new Item[num];
    }
}

public class MatrixTran {
    public static void main(String[] args) {
        SparseMatrix matrixA = new SparseMatrix(8);
        initMatrix(matrixA.elements);
        for (Item item : matrixA.elements) {
            System.out.printf("[%d, %d, %d]\n", item.row, item.col, item.item);
        }
        System.out.println("------------------------------------------------------");
        //method1(matrixA);
        method2(matrixA);
    }


    /**
     * 该方法的时间复杂度为 O(col * nums),思路就是简化后的遍历整个二维数组,现在就是不用遍历所有的元素,只需要在总元素范围内遍历就可
     * @param matrixA
     */
    private static void method1(SparseMatrix matrixA) {
        //初始化转置后的矩阵
        SparseMatrix matrixB = new SparseMatrix(8);
        Item[] elemsB = matrixB.elements;
        for(int i = 0; i < 8; i++) {
            elemsB[i] = new Item(0, 0, 0);
        }
        //使用时间复杂度为 O(col * number) 的算法
        int currentPos = 0;
        Item[] elemsA = matrixA.elements;
        for(int i = 0; i < 7; i++) {
            for(int j = 0; j < matrixA.num; j++) {
                if(i == elemsA[j].col) {
                    elemsB[currentPos].row = elemsA[j].col;
                    elemsB[currentPos].col = elemsA[j].row;
                    elemsB[currentPos].item = elemsA[j].item;
                    currentPos++;
                }
            }
        }

        for (Item item : elemsB) {
            System.out.printf("[%d, %d, %d]\n", item.row, item.col, item.item);
        }
    }

    /**
     * 方法二:时间复杂度为 O(max(A.cols, A.nums))
     * 思路:
     * 1、矩阵 A 经过转置变成 B 之后,列变成了行,我们先用一个数组 rowSize 来存储 B 的每行中有几个元素
     * 2、再用一个数组 rowStart 来存储 B 的每行第一个元素的起始位置,就是 rowSize[i - 1] + rowStart[i - 1]
     * 3、遍历 A 中的元素,每遍历到一个元素,我们就通过 rowStart[A.col] 来确定它的起始位置,
     *  在 B 中添加元素之后,把对应的该元素所在行的起始位置加一,以便下一个该行的元素可以知道自己的起始位置
     * @param matrixA
     */
    private static void method2(SparseMatrix matrixA) {
        //获得矩阵 A 中元素
        Item[] elemsA = matrixA.elements;
        //创建矩阵 B 并初始化
        SparseMatrix matrixB = new SparseMatrix(8);
        Item[] elemsB = matrixB.elements;
        for(int i = 0; i < 8; i++) {
            elemsB[i] = new Item(0, 0, 0);
        }
        //定义每行的元素总个数
        int[] rowSize = new int[8];
        //定义每行元素的起始位置
        int[] rowStart = new int[8];
        //初始化
        for(int i = 0; i < 8; i++) {
            rowSize[i] = 0;
            rowStart[i] = 0;
        }
        //设置每行元素有多少个
        for (Item item : elemsA) {
           rowSize[item.col]++;
        }
        //设置每行的第一个元素的起始位置
        for(int i = 0; i < matrixA.num; i ++) {
            if(i > 0) {
                rowStart[i] = rowStart[i - 1] + rowSize[i - 1];
            }
        }
        //往目标数组里面放元素
        for (Item item : elemsA) {
            int rowB = item.col;
            int pos = rowStart[rowB];   //pos 就是该元素在矩阵 A 中应该存储的位置
            elemsB[pos].row = item.col;
            elemsB[pos].col = item.row;
            elemsB[pos].item = item.item;
            rowStart[rowB]++;
        }

        //输出
        for (Item item : elemsB) {
            System.out.printf("[%d, %d, %d]\n", item.row, item.col, item.item);
        }
    }

    //初始化矩阵A
    private static void initMatrix(Item[] matrix) {
        matrix[0] = new Item(0, 2, 22);
        matrix[1] = new Item(0, 6, 15);
        matrix[2] = new Item(1, 1, 11);
        matrix[3] = new Item(1, 5, 17);
        matrix[4] = new Item(2, 3, -6);
        matrix[5] = new Item(3, 5, 39);
        matrix[6] = new Item(4, 0, 91);
        matrix[7] = new Item(5, 2, 28);
    }
}

发布了42 篇原创文章 · 获赞 3 · 访问量 2063

猜你喜欢

转载自blog.csdn.net/stable_zl/article/details/104764909
今日推荐