數據結構(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()+"\t"+data[i].getcol()+"\t"+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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM