目录
1.什么是稀疏数组
稀疏数组(sparse array)是一种针对具有大量重复或者值为零的元素的数组的优化表示方法。稀疏数组通过记录原始数组中非零元素的位置和值,来减少存储空间的占用。
在稀疏数组中,通常使用三元组的形式来表示非零元素,即记录元素的行号、列号和值。对于原始数组中的零元素,则不进行记录。
通过使用稀疏数组,可以有效地减少存储空间的占用,特别适用于处理大规模矩阵或者二维数组的情况。
2.稀疏数组的表示方法
稀疏数组的表示方法通常包括三个部分:原始数组的大小、非零元素的个数以及非零元素的值和位置。
1. 原始数组的大小:原始数组指的是需要压缩的数组,它的大小可以用两个整数表示,通常是行数和列数。
2. 非零元素的个数:指的是原始数组中非零元素的个数。
3. 非零元素的值和位置:通常用一个二维数组表示,每一行表示一个非零元素的值和位置。每一行包括三个元素,分别表示非零元素的值、行号和列号。
因此,稀疏数组的表示方法如下:
-
定义稀疏数组的格式:
[总行数, 总列数, 非默认值的个数] [行索引1, 列索引1, 值1] [行索引2, 列索引2, 值2] ... [行索引n, 列索引n, 值n]
其中,第一行表示原始数组的总行数、总列数、非默认值的个数。后续的行表示非默认值元素的行索引、列索引和值。
-
示例: 假设有一个原始数组 arr 如下:
0 0 0 0 5 0 0 0 0 3 0 0 0 0 7 0
对应的稀疏数组表示为:
4 4 5 1 0 5 2 1 3 3 2 7
第一行表示原始数组为 4 行 4 列,有 5 个非默认值。后续的行表示非默认值元素的行索引、列索引和值。
3.稀疏数组与二维数组的转换
稀疏数组和二维数组之间的转换可以通过以下步骤进行:
-
二维数组转换为稀疏数组:
- 遍历二维数组,统计非零元素的个数(即有效元素个数)。
- 创建一个稀疏数组,第一行记录二维数组的行数、列数和有效元素个数。
- 从第二行开始,记录每个非零元素的行索引、列索引和值。
-
稀疏数组转换为二维数组:
- 从稀疏数组的第一行读取二维数组的行数、列数和有效元素个数。
- 根据行数和列数创建一个二维数组,并初始化为0。
- 遍历稀疏数组的每一行,将非零元素的值填入二维数组的相应位置。
在进行转换时,需要注意稀疏数组和二维数组的存储结构和信息表示方式,以确保转换的准确性和完整性。
4.Java 代码转换示范
使用 Java 语言实现稀疏数组与二维数组的转换的示例代码:
如下图所示,我们有一个 11 × 11 的棋盘。为了保存这个棋局,我们首先使用二维数组来表示棋盘上每个位置的状态,然后将其转换为稀疏数组,最后再将稀疏数组恢复为二维数组。
public class Test {
// 使用 静态final 字段定义棋盘的行与列
// 确保唯一性,并且可以全局调用
private static final int ROWS = 11;
private static final int COLUMNS = 11;
public static void main(String[] args) {
// 创建一个二维数组表示棋盘
// 默认初始化全为 0 的二维数组
int[][] chessArray = new int[ROWS][COLUMNS];
// 在棋盘上放置棋子
// 1 代表黑子, 2 代表白子
chessArray[3][3] = 1;
chessArray[5][5] = 1;
chessArray[7][5] = 2;
chessArray[7][7] = 2;
System.out.println("原始二维数组");
printArray(chessArray); // 打印原始的二维数组
// 将二维数组转换为稀疏数组
int[][] sparseArray = convertToSparseArray(chessArray);
System.out.println("稀疏数组");
printArray(sparseArray);// 打印稀疏数组
// 将稀疏数组恢复为二维数组
int[][] restoredArray = restoreFromSparseArray(sparseArray);
System.out.println("转换后的二维数组");
printArray(restoredArray);// 打印转换后的二维数组
}
// 将二维数组转换为稀疏数组的方法
private static int[][] convertToSparseArray(int[][] array) {
int nonZeroCount = 0;
for (int[] row : array) {
for (int value : row) {
if (value != 0) {
nonZeroCount++; // 统计非零元素的个数
}
}
}
// 创建稀疏数组
int[][] sparseArray = new int[nonZeroCount + 1][3];
sparseArray[0][0] = ROWS; // 存储原始数组的行数
sparseArray[0][1] = COLUMNS; // 存储原始数组的列数
sparseArray[0][2] = nonZeroCount; // 存储非零元素的个数
int count = 0;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLUMNS; j++) {
if (array[i][j] != 0) {
count++;
sparseArray[count][0] = i; // 存储非零元素的行号
sparseArray[count][1] = j; // 存储非零元素的列号
sparseArray[count][2] = array[i][j]; // 存储非零元素的值
}
}
}
return sparseArray; // 返回稀疏数组
}
// 将稀疏数组恢复为二维数组的方法
private static int[][] restoreFromSparseArray(int[][] sparseArray) {
int row = sparseArray[0][0]; // 获取稀疏数组的行数
int column = sparseArray[0][1]; // 获取稀疏数组的列数
int count = sparseArray[0][2]; // 获取非零元素的个数
int[][] array = new int[row][column]; // 创建新的二维数组
for (int i = 1; i <= count; i++) {
int r = sparseArray[i][0]; // 获取非零元素的行号
int c = sparseArray[i][1]; // 获取非零元素的列号
int value = sparseArray[i][2]; // 获取非零元素的值
array[r][c] = value; // 将非零元素的值赋给二维数组
}
return array; // 返回恢复后的二维数组
}
// 打印数组的方法
private static void printArray(int[][] array) {
for (int[] row : array) {
for (int value : row) {
System.out.printf("%d\t", value); // 打印数组元素
}
System.out.println();
}
}
}
代码运行结果: