1.定义
稀疏数组可以看做是普通数组的压缩,但是这里说的普通数组是指无效数的据量远大于有效数据量的数组;
例如:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 2 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
其稀疏数组形式:
|row column value
0 | 11 11 2
1 | 1 2 1
2 | 2 4 2
2.存储
刚说到稀疏数组是一种压缩后的数组,为什么要进行压缩存储呢?
- 原数组中存在大量的无效数据,占据了大量的存储空间,真正有用的数据却少之又少
- 压缩存储可以节省存储空间以避免资源的不必要的浪费,在数据序列化到磁盘时,压缩存储可以提高IO效率
3.存储方式
3.1普通存储
示例:
|row column value
0 | 11 11 2
1 | 1 2 1
2 | 2 4 2
第0行数据:
row :代表原数组行数;
column:代表原数组列数;
value:代表原数组有效元素的个数;
其它行数据:
row :代表原数组有效元素所在行;
column:代表原数组有效元素所在列;
value:代表原数组有效元素的值;
3.2链式存储
以这个为例:
0 0 0 0 转稀疏数组 0| 4 4 3
0 1 0 0 -------> 1| 1 1 1
0 2 0 0 -------> 2| 2 1 2
0 0 3 0 3| 3 2 3
4.二维数组与稀疏数组的转换思路
4.1二维数组转稀疏数组
- 遍历原始二维数组,得到有效元素个数 sum;
- 根据 sum 创建稀疏数组
SparsArray[sum+1][3] - 将二维数组的元素存入到稀疏数组中
4.2稀疏数组转二维数组
- 先读取稀疏数组的第一行,根据第一行的数据,创建原始二维数组
- 根据稀疏数组其余行数据给原始数组赋值
5.代码实现
package com.beyond.datastructrue.sparsearray;
import java.io.*;
public class SparsArray {
public static void main(String[] args) throws IOException, ClassNotFoundException {
int[][] array = new int[11][11];
array[1][2] = 1;
array[2][3] = 2;
for (int[] row : array
) {
for (int item : row
) {
System.out.print(item + " ");
}
System.out.println();
}
System.out.println("-----------开始转稀疏数组----------");
int num = 0;
for (int[] row : array
) {
for (int item : row
) {
if (item != 0) {
num++;
}
}
}
System.out.println("得到原始数组的有效元素个数为:" + num);
int[][] sparsArray = new int[num + 1][3];
sparsArray[0][0] = array.length;
sparsArray[0][1] = array[0].length;
sparsArray[0][2] = num;
int index = 1;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[0].length; j++) {
if (array[i][j] != 0) {
sparsArray[index][0] = i;
sparsArray[index][1] = j;
sparsArray[index][2] = array[i][j];
index++;
}
}
}
System.out.println("打印转换后的稀疏数组:");
for (int[] row : sparsArray
) {
for (int item : row
) {
System.out.print(item + " ");
}
System.out.println();
}
System.out.println("-----------稀疏数恢复为原始数组----------");
int rowNum = sparsArray[0][0];
int colNum = sparsArray[0][1];
int[][] originalArray = new int[rowNum][colNum];
for (int i = 1; i < sparsArray.length; i++) {
originalArray[sparsArray[i][0]][sparsArray[i][1]] = sparsArray[i][2];
}
System.out.println("-----打印恢复的原始数组------");
for (int[] row : originalArray
) {
for (int item : row
) {
System.out.print(item + " ");
}
System.out.println();
}
FileOutputStream fileOutputStream = new FileOutputStream("D:\\array.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(sparsArray);
fileOutputStream.close();
objectOutputStream.close();
FileInputStream fileInputStream = new FileInputStream("D:\\array.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
int[][] objectAaaay = (int[][]) objectInputStream.readObject();
fileInputStream.close();
objectInputStream.close();
System.out.println("--------------------------");
for (int[] row : objectAaaay
) {
for (int item : row
) {
System.out.print(item + " ");
}
System.out.println();
}
}
}
打印结果:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
-----------开始转稀疏数组----------
得到原始数组的有效元素个数为:2
打印转换后的稀疏数组:
11 11 2
1 2 1
2 3 2
-----------稀疏数恢复为原始数组----------
-----打印恢复的原始数组------
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
--------------------------
11 11 2
1 2 1
2 3 2
|