什么是稀疏数组
稀疏数组是一种数据结构,用于表示大部分元素为默认值(通常为零或空)的数组,而仅存储非默认值的元素及其对应的索引。这种表示方式可以有效地节省内存空间,尤其是在处理稀疏数据时,即大多数元素都是默认值的情况下。
稀疏数组通常由两个数组组成:索引数组和值数组。索引数组存储非默认值的元素在原始数组中的索引位置,而值数组则存储这些非默认值元素的值。通过这种方式,只需要存储实际存在值的元素,而不需要存储默认值,从而减少了内存的使用量。
话不多说,看代码实现,如下这里主要例子如棋盘棋子形态。将例如棋盘信息存档等进行操作,它存在大量的空格,我们就只需要把有棋子的存储起来,减少操作存储开销。
1、定义一个棋盘数组
int[][] arr = new int[8][8];
arr[0][3] = 1;
arr[3][4] = 1;
arr[5][2] = 1;
arr[1][2] = 2;
arr[5][6] = 2;
结果如下:
0 0 0 1 0 0 0 0
0 0 2 0 0 0 0 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 0 1 0 0 0 2 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
2、将棋盘存为稀疏数组
稀疏数组格式:
类型 | 行坐标 | 列坐标 | 值 |
---|---|---|---|
规模 | 数组总行数 | 数组总列数 | 非零数据个数 |
8 | 8 | 5 | |
数据 | 数据行坐标 | 数据列坐标 | 数据 |
0 | 3 | 1 | |
1 | 2 | 2 | |
3 | 4 | 1 | |
5 | 2 | 1 | |
5 | 6 | 2 |
求稀疏数组的数组大小,规模信息
int arrRowCount = arr.length;
int arrColCount = arr[0].length;
// 确定稀疏数组的数组大小
int noZeroValCount = 0;
for (int[] rowArr : arr) {
for (int ele : rowArr) {
if (ele != 0) {
noZeroValCount++;
}
}
}
根据求出的信息定义稀疏数组对象
// 确定稀疏数组大小
int[][] spareArr = new int[noZeroValCount + 1][3];
// 存放原始棋盘大小
spareArr[0][0] = arrRowCount;
spareArr[0][1] = arrColCount;
spareArr[0][2] = noZeroValCount;
然后将非空数据存放进去,结果如下
int count = 0;
// 将非零元素转换到稀疏数组
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
if (arr[i][j] != 0) {
count++;
spareArr[count][0] = i;
spareArr[count][1] = j;
spareArr[count][2] = arr[i][j];
}
}
}
8 8 5
0 3 1
1 2 2
3 4 1
5 2 1
5 6 2
2、将稀疏数组还原
// 取出稀疏数组第一行元素定义原数组的大小
int[][] normal = new int[spareArr[0][0]][spareArr[0][1]];
// 遍历稀疏数组还原
for (int i = 1; i <= spareArr[0][2]; i++) {
normal[spareArr[i][0]][spareArr[i][1]] = spareArr[i][2];
}
0 0 0 1 0 0 0 0
0 0 2 0 0 0 0 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 0 1 0 0 0 2 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
稀疏数组并不适用于所有的情况,根据实际情况而定。
完整源码:
/**
* 稀疏数组
* 将例如棋盘信息存档等进行操作,它存在大量的空格,我们就只需要把有棋子的存储起来,减少操作存储开销
* 普通二维数组转稀疏数组
* 1、定义一个棋盘数组
* 2、将棋盘存为稀疏数组
* 1)稀疏数组第一行存储棋盘数组总行数,总列数和非零元素总个数
* 2)二行开始存储每一行的非零数据的行列坐标和值
*
* @author hexionly
* @datetime 2024/04/11 13:42:01
*/
public class SpareArrays {
public static void main(String[] args) {
int[][] arr = new int[8][8];
arr[0][3] = 1;
arr[3][4] = 1;
arr[5][2] = 1;
arr[1][2] = 2;
arr[5][6] = 2;
printArray(arr);
System.out.println("------------------------------------------");
int[][] spareArray = castSpareArray(arr);
printArray(spareArray);
System.out.println("------------------------------------------");
int[][] normalArray = spareArrayCastNormalArray(spareArray);
printArray(normalArray);
}
/**
* 数组转换成稀疏数组
*
* @param arr 原数组
*/
private static int[][] castSpareArray(int[][] arr) {
int arrRowCount = arr.length;
int arrColCount = arr[0].length;
// 确定稀疏数组的数组大小
int noZeroValCount = 0;
for (int[] rowArr : arr) {
for (int ele : rowArr) {
if (ele != 0) {
noZeroValCount++;
}
}
}
// 确定稀疏数组大小
int[][] spareArr = new int[noZeroValCount + 1][3];
// 存放原始棋盘大小
spareArr[0][0] = arrRowCount;
spareArr[0][1] = arrColCount;
spareArr[0][2] = noZeroValCount;
int count = 0;
// 将非零元素转换到稀疏数组
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
if (arr[i][j] != 0) {
count++;
spareArr[count][0] = i;
spareArr[count][1] = j;
spareArr[count][2] = arr[i][j];
}
}
}
return spareArr;
}
/**
* 稀稀数组转换成普通数组
*
* @param spareArr 稀疏数组
*/
private static int[][] spareArrayCastNormalArray(int[][] spareArr) {
// 取出稀疏数组第一行元素定义原数组的大小
int[][] normal = new int[spareArr[0][0]][spareArr[0][1]];
// 遍历稀疏数组还原
for (int i = 1; i <= spareArr[0][2]; i++) {
normal[spareArr[i][0]][spareArr[i][1]] = spareArr[i][2];
}
return normal;
}
/**
* 打印数组
*
* @param arr 数组
*/
private static void printArray(int[][] arr) {
for (int[] rowArr : arr) {
for (int ele : rowArr) {
System.out.print(ele + "\t");
}
System.out.println();
}
}
}