五子棋程序,只有两种颜色的子,连成五个就gameover。可能一个棋盘能放下100枚棋子,但是总占用空间只有不到10个,游戏就over了。那么这样存储到本地file的话,空间是极大的浪费的。这就引出了稀疏数组。
当一个数组中大部分元素都是0(或是同一个值)的时候,就可以用稀疏数组来保存此数组。
三、什么是稀疏数组1、图解
先有个原始数组,8*7的规模,如下
2、分析
明显发现0值的数量远大于有效数据(这里非0值代表有效数据)。而且是个数组形式,所以稀疏数组来了!拆解成下稀疏数组有如下几点:
- 先统计出原始数组的总行数、总列数、总有效数据数作为稀疏数组的第一行。
- 将有效数据的行列的位置以及数值存储到稀疏数组中。
比如上面的表格换成稀疏数组的存法就如下:
可以发现:
稀疏数组永远都是三列。
原始数组存法的话需要87=56个元素空间
稀疏数组存法的话需要113=33个元素空间,效果很明显
3、代码
用代码证明上述图片,代码中有详细的关键性注释,一看就懂。
package com.chentongwei.struct.sparsearray;
/**
* Description: 稀疏数组
*
* @author TongWei.Chen 2019-12-12 14:39:08
*/
public class MySparseArray3 {
public static void main(String[] args) {
int[][] originArray = new int[8][7];
originArray[0][2] = 12;
originArray[0][4] = 2;
originArray[1][1] = 1;
originArray[2][3] = -5;
originArray[3][5] = 10;
originArray[4][0] = 1;
originArray[6][0] = 55;
originArray[6][3] = 4;
originArray[7][0] = 7;
originArray[7][4] = 20;
System.out.println("---------------------原始数组---------------------");
// print原始数组
print(originArray);
System.out.println("---------------------稀疏数组---------------------");
// 原始数组转稀疏数组
int[][] spraseArray = originToSparse(originArray);
print(spraseArray);
System.out.println("---------------------原始数组---------------------");
// 稀疏数组转原始数组
int[][] originArray2 = sparseToOrigin(spraseArray);
print(originArray2);
}
// print
private static void print(int[][] array) {
for (int[] arr : array) {
for (int data : arr) {
System.out.printf("%d\t", data);
}
System.out.println();
}
}
// 原始数组->稀疏数组
private static int[][] originToSparse(int[][] originArray) {
// 先找到有效元素行(个)数
int count = 0;
for (int i = 0; i < originArray.length; i++) {
for (int j = 0; j < originArray[i].length; j ++) {
if (originArray[i][j] != 0) {
count ++;
}
}
}
// 为什么是count + 1?因为count代表有效数据行数,但是再顶部还有一个总的行数、列数、值数
int[][] spraseArray = new int[count + 1][3];
// 为稀疏数组的第一行赋值
spraseArray[0][0] = originArray.length;
spraseArray[0][1] = originArray[0].length;
spraseArray[0][2] = count;
// 组装稀疏数组
int index = 0;
for (int i = 0; i < originArray.length; i++) {
for (int j = 0; j < originArray[i].length; j ++) {
if (originArray[i][j] != 0) {
index ++;
spraseArray[index][0] = i;
spraseArray[index][1] = j;
spraseArray[index][2] = originArray[i][j];
}
}
}
return spraseArray;
}
// 稀疏数组->原始数组
private static int[][] sparseToOrigin(int[][] sparseArray) {
// 先构建出原始数组的行列
int[][] originArray = new int[sparseArray[0][0]][sparseArray[0][1]];
// 再往上面卯值
for (int i = 1; i < sparseArray.length; i ++) {
for (int j = 0; j < sparseArray[i].length; j ++) {
originArray[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][j];
}
}
return originArray;
}
}