• 数据结构(java语言描述)串与数组——稀疏矩阵的三元组表存储


    知识点补充:

    稀疏矩阵:是具有较多零元素且非零元素的分布无规律的矩阵。(一般矩阵是用多(二)维数组存储)。

    但是,稀疏矩阵的存储比较浪费存储空间,因此为了节省存储空间可以用一个三元组表来存储稀疏矩阵。

    三元组表:三元组表中的任意一个三元组元素存储了稀疏矩阵中的非零元素、所在行和所在列。

    稀疏矩阵转三元表表示的原理图如下(ps手写版,比较快,将就看吧,主要是能明白^~^):

    java语言表示的三元组(结点)的类形式:

    package chuanshu;
    class tripleNode {//三元组的定义
        private int row;//元素所在稀疏矩阵中的行号
        private int col;//元素所在稀疏矩阵中的列号
        private int value;//元素所在稀疏矩阵中的非零元素值
        public int getcol(){
            return col;
        }
        public int getrow(){
            return row;
        }
        public void setcol(int col){
            this.col=col;
        }
        public void setrow(int row){
            this.row=row;
        }
        public int getvalue(){
            return value;
        }
        public void setvalue(int value){
            this.value=value;
        }
        public tripleNode(int row,int col,int value){//带行列值参数的构造方法
            this.row=row;
            this.col=col;
            this.value=value;
        }
        public tripleNode(){//无参构造方法
            this(0,0,0);
        }
    }

    这是三元组表中存储一个非零元素的结点。

    然后采用一个tripleNode类型的数组data来存储整个稀疏矩阵(多个元素结点构成了表的形式),此外还要设置成员变量来存储稀疏矩阵的行数、列数和非零元素的个数。cols/rows/nums

    稀疏矩阵的三元组表的类定义:

    package chuanshu;
    /***********三元组就是用一个以为数组存储所有的元素,每个结点记录该元素在数组(矩阵)中是所在的行和列******************/
    public class SparseMatrix {
    private int rows;//稀疏矩阵的行数
    private int cols;//稀疏矩阵总的列数
    private int nums;//稀疏矩阵非0元素个数
    private tripleNode data[];//三元组数据结点
    public tripleNode[] getedata(){//返回某个三元组结点的数据值
        return data;
    }
    public void setdata(tripleNode[] data){//给三元组的数据结点赋值(三元组形式row col value)
        this.data=data;
    }
    public int getcosl(){//获取稀疏矩阵的的总列数
        return cols;
    }
    public int getrows(){//获取稀疏矩阵的的总行数
        return rows;
    }
    public void setcols(int cols){//设置稀疏矩阵的的总列数
        this.cols=cols;
    }
    public void setrows(int rows){//设置稀疏矩阵的的总行数
        this.rows=rows;
    }
    public int getnums(int nums){//获取整个稀疏矩阵的非零元素个数
        return nums;
    }
    public void setnums(int nums){//设置整个稀疏矩阵的非零元素个数
        this.nums=nums;
    }
    public SparseMatrix(int maxsize){//初始化函数
        data=new tripleNode[maxsize];
        for(int i=0;i<data.length;i++){
            data[i]=new tripleNode();
        }
        rows=0;
        cols=0;
        nums=0;
    }
    public SparseMatrix(int mat[][]){//用数组初始化的构造函数
        int i,j,k=0,count=0;
        rows=mat.length;
        cols=mat.length;
        for(i=0;i<mat.length;i++){//先计算数组mat[][]的非零元素个数
            for(j=0;j<mat.length;j++){
                if(mat[i][j]!=0){
                    count++;
                }
            }
        }
        nums=count;
        data=new tripleNode[nums];//初始化三元组(顺序表存储模式)
        for(i=0;i<mat.length;i++){
            for(j=0;j<mat.length;j++){
                if(mat[i][j]!=0){
                    data[k]=new tripleNode(i,j,mat[i][j]);//把mat[][]中所有不等于零的元素赋值给三元组
                    k++;
                }
            }
        }
    }
    public void printMatrix(){//打印整个三元组的所有结点
        int i;
        System.out.println("稀疏矩阵的三元组存储结构:");
        System.out.println("行数:"+rows+"列数:"+cols+"非零元素的个数:"+nums);
        System.out.println("行下标 列下标 元素值");
        for(i=0;i<nums;i++){
            System.out.println(data[i].getrow()+" "+data[i].getcol()+" "+data[i].getvalue());
        }
    }

    /******转置思想:初始化一个新的三元组表;然后,对稀疏举证的n列进行扫描,当扫描第i列的时候,遍历整个三元组表的t个元素。若元素所在列=i,则将这个元素的值赋给新的三元组表的结点值,然后让这个元素的列作为新三元组表元素的行,这个元素的行作为新三元组表元素的列,另新三元组表元素下标加1;*****/

    /***************算法时间复杂度O(nt),空间复杂度O(t)****************************/
    public SparseMatrix transpose(){//返回的是一个三元组对象,转置
        SparseMatrix tm=new SparseMatrix(nums);
        tm.cols=rows;
        tm.rows=cols;
        tm.nums=nums;
        int q=0;//三元组结点data[]的下标
        for(int col=0;col<cols;col++){
            for(int p=0;p<nums;p++){
                if(data[p].getcol()==col){
                    tm.data[q].setrow(data[p].getcol());
                    tm.data[q].setcol(data[p].getrow());
                    tm.data[q].setvalue(data[p].getvalue());
                    q++;//
                }
            }
        }
        return tm;
    }

    /***********fasttranspose方法:初始化一个三元组表;然后,分别计算原稀疏矩阵每列之前的非零元素个数,即为转置后的每行元素之前的非零元素的个数赋值给num[cols],***************/

    /**************************/
    public SparseMatrix  fasttranspose(){//返回的是一个三元组表对象,快速转置
        SparseMatrix tm=new SparseMatrix(nums);//生成一个新的三元组表对象
        tm.cols=rows;
        tm.rows=cols;
        tm.nums=nums;//设置新表的列行和非零元素个数
        int i,j=0,k=0;
        int[] num,cpot;
        if(nums>0){
            num=new int[cols];//初始化一个列数大小的数组
            cpot=new int[cols];//初始化一个列数大小的数组
            for(i=0;i<cols;i++){
                num[i]=0;
            }
            for(i=0;i<nums;i++){
                j=data[i].getcol();//获取每个非零元素在原稀疏矩阵N中所在的列数
                num[j]++;//计算每列有多少个非零元素,num[j]最终存储原稀疏矩阵N中每列非零元素的个数
            }
            cpot[0]=0;
            for(i=1;i<cols;i++){//对1到总列数进行遍历
                cpot[i]=cpot[i-1]+num[i-1];//cpot[i]表示原稀疏矩阵N中第i列的第一个元素在转置后的稀疏矩阵M的三元组表TM中的位置(下标)
            }
            for(i=0;i<nums;i++){//对TN所有的非零元素进行遍历
                j=data[i].getcol();//返回原TN第i个非零元素所在的列数
                k=cpot[j];//返回N中第j列的第一个非零元素在TM中的下标
                tm.data[k].setrow(data[i].getcol());
                tm.data[k].setcol(data[i].getrow());
                tm.data[k].setvalue(data[i].getvalue());
                cpot[j]++;/***/N中的同一列中的元素大于一则执行+1,即该元素在TM中的下标加1(N中的同一列即为M中的同一行,所以TN中同一列的元素不相邻,但在TM中相邻)****/

    图示:


            }
        }
        return tm;
    }
    }
    调用的主函数:

    package chuanshu;
    public class juzhen {
        public static void main(String[] args){
            int m[][]={{0,0,8,0,0,0},{0,0,0,0,0,0},{5,0,0,0,16,0},{0,0,18,0,0,0},{0,0,0,9,0,0}};
            SparseMatrix sm=new SparseMatrix(m);
            SparseMatrix tm=sm.transpose();
            SparseMatrix tsm=sm.fasttranspose();
            sm.printMatrix();
            tm.printMatrix();
            tsm.printMatrix();
        }
    }

    结果:

    稀疏矩阵的三元组存储结构:
    行数:5列数:6非零元素的个数:5
    行下标 列下标 元素值
    0    2    8
    2    0    5
    2    4    16
    3    2    18
    4    3    9
    稀疏矩阵的三元组存储结构:
    行数:6列数:5非零元素的个数:5
    行下标 列下标 元素值
    0    2    5
    2    0    8
    2    3    18
    3    4    9
    4    2    16
    稀疏矩阵的三元组存储结构:
    行数:6列数:5非零元素的个数:5
    行下标 列下标 元素值
    0    2    5
    2    0    8
    2    3    18
    3    4    9
    4    2    16

  • 相关阅读:
    easyui 动态列
    easyui editor combobox multiple
    千年老二
    Win7上Git安装及配置过程
    Tomcat自动部署
    Win7下安装git
    修改mysql默认字符集的方法
    oracle 查询当前库中所有表以及某表字段信息
    treegrid and datagrid ctrl or shift selectRow
    条件注释判断浏览器<!--[if !IE]><!--[if IE]><!--[if lt IE 6]><!--[if gte IE 6]>
  • 原文地址:https://www.cnblogs.com/xleer/p/5341758.html
Copyright © 2020-2023  润新知