知识点补充:
稀疏矩阵:是具有较多零元素且非零元素的分布无规律的矩阵。(一般矩阵是用多(二)维数组存储)。
但是,稀疏矩阵的存储比较浪费存储空间,因此为了节省存储空间可以用一个三元组表来存储稀疏矩阵。
三元组表:三元组表中的任意一个三元组元素存储了稀疏矩阵中的非零元素、所在行和所在列。
稀疏矩阵转三元表表示的原理图如下(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