稀疏数组
所谓稀疏数组就是数组中大部分的内容值都未被使用(或都为零),在数组中仅有少部分的空间使用。因此造成内存空间的浪费,为了节省内存空间,并且不影响数组中原有的内容值,我们可以采用一种压缩的方式来表示稀疏数组的内容。
简单来说,稀疏数组就是将数组中有值的部分记录下来,从而节约内存空间。
到底什么地方需要用到稀疏数组呢,五子棋,扫雷等等这些典型可以应用稀疏数组来完成。
例如一个矩阵:
[ 0 0 0 0 0 0 0 1 0 0 0 0 0 2 0 0 3 0 0 0 0 0 0 0 0 ] \begin{bmatrix} 0& 0& 0& 0 &0 \\ 0& 0& 1& 0&0 \\ 0& 0& 0& 2&0 \\ 0& 3& 0& 0& 0\\ 0& 0& 0& 0&0 \end{bmatrix} ⎣⎢⎢⎢⎢⎡0000000030010000020000000⎦⎥⎥⎥⎥⎤
我们看到这个矩阵,显然它的 0 元素太多了,我们应该把该矩阵压缩成一个更小的矩阵,只保留有效的数字。一般我们压缩为为 n 行 3 列的矩阵。
压缩后的矩阵:
行 | 列 | 值 | |
---|---|---|---|
[0] | 5 | 5 | 3 |
[1] | 1 | 2 | 1 |
[2] | 2 | 3 | 2 |
[3] | 3 | 1 | 3 |
[ 5 5 3 1 2 1 2 3 2 3 1 3 ] \begin{bmatrix} 5& 5& 3\\ 1& 2& 1\\ 2& 3& 2\\ 3& 1& 3 \end{bmatrix} ⎣⎢⎢⎡512352313123⎦⎥⎥⎤
- 第一行:原始矩阵有几行几列,有几个有效值。
- 第n行:原始矩阵对应的有效值所在的行和列。
- 不难看出,原始矩阵本来有 5 × \times × 5 = 25 个元素,压缩后只剩 4 × \times × 3 = 12 个元素。
代码实现如下:
//创建一个原始的二维数组11*11
//0:没有棋子;1:黑子;2:蓝子
int[][] chessArr1 =new int[5][5];
chessArr1[1][2]=1;
chessArr1[2][3]=2;
chessArr1[3][1]=3;
System.out.println("原始的二维数组:");
for (int[] row : chessArr1){
for (int data : row){
System.out.print(data+"\t");
}
System.out.println();
}
//记录有几个有效数字
int sum=0;
for (int i=0;i<5;i++){
for (int j=0;j<5;j++){
if (chessArr1[i][j]!=0){
sum++;
}
}
}
//创建稀疏数组
int[][] sparseArr1 = new int[sum+1][3];
sparseArr1[0][0]=5;
sparseArr1[0][1]=5;
sparseArr1[0][2]=sum;
int count=0;//记录第几个非0数据
for (int i=0;i<5;i++){
for (int j=0;j<5;j++){
if (chessArr1[i][j]!=0){
count++;
sparseArr1[count][0]=i;
sparseArr1[count][1]=j;
sparseArr1[count][2]=chessArr1[i][j];
}
}
}
System.out.println("稀疏数组:");
for (int[] row : sparseArr1){
for (int data : row){
System.out.print(data+"\t");
}
System.out.println();
}
//将稀疏数组变回原始数组
int[][] chessArr2 = new int[sparseArr1[0][0]][sparseArr1[0][1]];
for(int i=1;i<sparseArr1.length;i++){
chessArr2[sparseArr1[i][0]][sparseArr1[i][1]]=sparseArr1[i][2];
}
System.out.println("变回原始数组:");
for(int[]arr:chessArr2){
for(int data:arr){
System.out.print(data+"\t");
}
System.out.println();
}