什么是稀疏矩阵?
一个矩阵中,如果大部分元素都是0,只有少部分是非0元素,这个矩阵就叫做稀疏矩阵。如下图所示,下面这个矩阵只有第1行第2列和第2行第4列的元素不为空,这个矩阵就是一个稀疏矩阵。
通常,我们用二维数组表示矩阵,但我们用二维数组表示稀疏矩阵时,二维数组里会存大量的0元素,占用内存,极大的浪费空间。这个时候我们通常会对稀疏矩阵进行压缩,让二维数组只存储非0元素,如下图所示。
假设压缩后的二维数组为B,B的第0行用来存储稀疏矩阵的相关信息。如B[0][0]表示稀疏矩阵一共有多少行,B[0][1]表示稀疏矩阵一共有多少列,B[0][2]表示稀疏矩阵一共有多少个非0元素。
从第一行开始,分别表示非0元素的行,列,值。
以B数组的第一行为例,表示存在一个行为1,列为2,值为1的非0元素。这样存储的二维数组就是压缩后的稀疏矩阵,只存储了关键信息。
private static int [][] arrayCompression(int[][] A){ //将稀疏矩阵A传过来
int sum=0;
int k=1;
for(int i=0;i<A.length;i++)
for(int j=0;j<A[i].length;j++)
if(A[i][j]!=0)
sum++;
int [][] B=new int[sum+1][3];
B[0][0]=A.length;
B[0][1]=A[0].length;
B[0][2]=sum;
for(int i=0;i<A.length;i++)
for(int j=0;j<A[i].length;j++)
if(A[i][j]!=0){ //元素不等于0就存在B中
B[k][0]=i;
B[k][1]=j;
B[k][2]=A[i][j];
k++;
}
return B;//返回压缩后的矩阵B
如何把压缩后的矩阵还原成原稀疏矩阵,取B数组第0行的行、列信息,建立一个行为11,列为11的新数组C。然后把B数组的非0元素信息依次赋值给给C数组就行了。
private static int[][] toSparseMatrix(int[][] B) {
int row=B[0][0];//B[0][0]存放稀疏矩阵的行
int list=B[0][1];//B[0][1]存放稀疏矩阵的列
int [][] C=new int[row][list];
for(int k=1;k<B.length;k++)
{
int i=B[k][0];
int j=B[k][1];
C[i][j]=B[k][2];
}
return C;//返回还原后的稀疏矩阵
}
全部实现代码
public class SparseArray {
public static void main(String[] args) {
int [][] A=new int[11][11];
A[1][2]=1;
A[2][4]=2;
System.out.println("输出原稀疏矩阵:");
outPutArray(A); //输出稀疏矩阵A
int [][] B= arrayCompression(A); //将稀疏矩阵A压缩 返回压缩以后的新矩阵B(二维)
System.out.println("输出稀疏矩阵压缩后的二维矩阵:");
outPutArray(B); //输出新矩阵B
System.out.println("输出压缩还原以后的稀疏矩阵:");
int[][] C=toSparseMatrix(B); //把矩阵B还原成稀疏矩阵
outPutArray(C);
}
private static int[][] toSparseMatrix(int[][] B) {
int row=B[0][0];//B[0][0]存放稀疏矩阵的行
int list=B[0][1];//B[0][1]存放稀疏矩阵的列
int [][] A=new int[row][list];
for(int k=1;k<B.length;k++)
{
int i=B[k][0];
int j=B[k][1];
A[i][j]=B[k][2];
}
return A;
}
private static void outPutArray(int[][] T) {
for(int[] row :T ) {
for (int data : row) {
System.out.print(data + "\t");
}
System.out.println();
}
}
public static int [][] arrayCompression(int[][] A){ //转为稀疏矩阵
int sum=0;
int k=1;
for(int i=0;i<A.length;i++)
for(int j=0;j<A[i].length;j++)
if(A[i][j]!=0)
sum++;
int [][] B=new int[sum+1][3];
B[0][0]=A.length;
B[0][1]=A[0].length;
B[0][2]=sum;
for(int i=0;i<A.length;i++)
for(int j=0;j<A[i].length;j++)
if(A[i][j]!=0){
B[k][0]=i;
B[k][1]=j;
B[k][2]=A[i][j];
k++;
}
return B;
}
}