知識點補充:
稀疏矩陣:是具有較多零元素且非零元素的分布無規律的矩陣。(一般矩陣是用多(二)維數組存儲)。
但是,稀疏矩陣的存儲比較浪費存儲空間,因此為了節省存儲空間可以用一個三元組表來存儲稀疏矩陣。
三元組表:三元組表中的任意一個三元組元素存儲了稀疏矩陣中的非零元素、所在行和所在列。
稀疏矩陣轉三元表表示的原理圖如下(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
