数组
稀疏数组(SparseArray)
概念:指在一个大部分元素为零的矩阵中,只记录非零元素及其位置信息的数据结构。
作用:使用正常的二位数组的话,就会存在大量的0,使用稀疏数组可以节省存储空间和提高处理效率。(可以理解为压缩了数组的空间,但是数据没有任何影响)
假设我们有一个二维数组,其主要元素为零,仅有少量非零值。我们可以将这个二维数组转换为稀疏数组,用一个三元组(行索引,列索引,值)来表示每个非零元素的位置和数值。
例如,给定一个5x5的二维数组:
0 0 0 0 0 0 5 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0
可以转换为如下形式的稀疏数组:
row col val 5 5 3 // 原始数组的行数、列数、非零元素的数量 1 1 5 2 2 2
第0行的第一个数表示有5行
-
对应上面二维数组的 5行
第0行的第二个数表示有5列
-
对应上面二维数组的 5列
第0行的第三个数表示有效数字有多少个
-
对应上面二维数组有多少 非零数
之后的几行记录二维数的非零数字的行、列和值
-
例如:稀疏数组的第1行
-
row = 1 表示第1行的位置
-
col = 1 表示第1列的位置
-
val = 5 该点的值为5
-
应用:比如记录五子棋的白子和黑子
代码实现
1.定义二维数组
这里我将非零数认定为 有效值
int[][] arr = new int[11][11];
arr[1][2] = 1;
arr[2][3] = 2;
//用作于记录非零的有效值
int sum = 0;
//获取二维数组的行数
int row = arr.length;
//获取二维数组的列数
int col = arr[0].length;
//进行二位数组的遍历
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
//打印二维数组
System.out.printf("%d\t",arr[i][j]);
//判断二维数组的非零数
if (arr[i][j] != 0) {
//记录二位数组的非零有效值
sum++;
}
}
System.out.println();
}
//1.二维数组转稀疏数组
//创建稀疏数组
int[][] sparseArray = new int[sum+1][3];
//1.1.获取当前数组的row colum value,给稀疏数组设置值
//定义稀疏数组的行
sparseArray[0][0] = array.length;
//定义稀疏数组的列
sparseArray[0][1] = array[0].length;
//定义稀疏数组的该位置的值
sparseArray[0][2] = sum;
//1.2.将现有的值的row colum value 保存到稀疏数组
int count = 0; //叠加有效数据的下标
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[0].length; j++) {
if (array[i][j] != 0) {
count++;//从下标1开始,因为下标0以及用来记录二维数组的行、列和有效值了
sparseArray[count][0] = i;//记录该有效值的行
sparseArray[count][1] = j;//记录该有效值的列
sparseArray[count][2] = array[i][j];//记录该有效值
}
}
}
完整实现代码
public class SparseArray {
public static void main(String[] args) {
int[][] array = new int[11][11];
array[1][2] = 1;
array[2][3] = 2;
array[4][2] = 1;
array[5][2] = 1;
System.out.println("--------------二维数组---------------");
int sum = 0;
for (int[] a: array) {
for (int b : a) {
System.out.printf("%d\t",b);
// 获取当前有多少个有效值
if (b != 0) {
sum++;
}
}
System.out.println();
}
//1.二维数组转稀疏数组
//创建稀疏数组
int[][] sparseArray = new int[sum+1][3];
//1.1.获取当前数组的row colum value,给稀疏数组设置值
//定义稀疏数组的行
sparseArray[0][0] = array.length;
//定义稀疏数组的列
sparseArray[0][1] = array[0].length;
//定义稀疏数组的该位置的值
sparseArray[0][2] = sum;
//1.2.将现有的值的row colum value 保存到稀疏数组
int count = 0; //叠加有效数据的下标
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[0].length; j++) {
if (array[i][j] != 0) {
count++;
sparseArray[count][0] = i;
sparseArray[count][1] = j;
sparseArray[count][2] = array[i][j];
}
}
}
}
}
TODO:可以将该稀疏数组进行磁盘化保存到本地
用到了IO流的知识
try (FileOutputStream fos = new FileOutputStream("twoDArrayData.dat");
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
// 序列化二维数组并写入文件
oos.writeObject(array);
System.out.println("二维数组已成功写入磁盘。");
} catch (IOException e) {
e.printStackTrace();
}
try (FileInputStream fis = new FileInputStream("twoDArrayData.dat");
ObjectInputStream ois = new ObjectInputStream(fis)) {
// 从文件读取并反序列化二维数组
int[][] towArray = (int[][]) ois.readObject();
System.out.println("二维数组已成功从磁盘读取:");
for (int[] row : towArray) {
for (int num : row) {
System.out.printf("%d\t",num);
}
System.out.println();
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}