一、稀疏数组的应用场景
当一个原始二维数组大部分元素为 0 ,或者为同一个值时,可以使用稀疏数组来保存该数组。
二、如何将原始的二维数组转化为稀疏数组
如图所示:
- 稀疏数组共有 3 列。
- 稀疏数组的第一行分别记录原始二维数组的行的总数、列的总数以及有效元素的总数(元素值不为 0)。
- 稀疏数组的其他行用来记录在二维数组中的每一个有效元素的行序号、列序号、以及对应元素的值。
三、稀疏数组的实际应用
1、使用稀疏数组来记录棋盘(存档)
思路分析:
- 遍历二维数组,获取二维数组中有效元素个数 sum。
- 根据 sum 创建稀疏数组 sparseArr int[sum + 1][3]
- 将二维数组的有效元素存入稀疏数组。
package cn.edu.imau.sparsearray;
public class SparseArray {
public static void main(String[] args) {
// 创建一个原始的二维数组 11 * 11
// 0:没有棋子 1:黑子,2:蓝子
int chessArr1[][] = new int[11][11];
chessArr1[1][2] = 1;
chessArr1[2][3] = 2;
chessArr1[3][4] = 2;
// 输出原始的二维数组
for (int[] row : chessArr1) {
for (int data : row) {
System.out.printf("%d\t", data);
}
System.out.println();
}
// 二维数组转化成稀疏数组
// 1. 遍历二维数组,得到有效数组个数(非零)
int sum = 0;
for (int[] row : chessArr1) {
for (int data : row) {
if (data != 0) {
sum += 1;
}
}
}
// 2. 创建稀疏数组 [sum + 1][3]
int[][] sparseArr = new int[sum + 1][3];
// 3. 将二维数组的行数、列数、有效值个数放入第一行
sparseArr[0][0] = chessArr1.length;
sparseArr[0][1] = chessArr1[0].length;
sparseArr[0][2] = sum;
// 4. 遍历二维数组,将有效值得所在行列及值放入稀疏数组其他行
int k = 1; // 记录稀疏数组目前的行数
int cnt = 0; // 记录找到的有效值
for (int i = 0; i < chessArr1.length; i++) {
for (int j = 0; j < chessArr1[0].length; j++) {
if (chessArr1[i][j] != 0) {
// 行
sparseArr[k][0] = i;
// 列
sparseArr[k][1] = j;
// 值
sparseArr[k++][2] = chessArr1[i][j];
cnt++;
}
// 找到所有的有效值,结束循环。
if (cnt == sum) {
break;
}
}
}
System.out.println();
System.out.println("得到的稀疏数组的形式为:");
// 打印稀疏数组
for (int i = 0; i < sparseArr.length; i++) {
System.out.printf("%d\t%d\t%d\t\n", sparseArr[i][0], sparseArr[i][1], sparseArr[i][2]);
}
}
}
2、恢复棋盘(稀疏数组恢复为二维数组)
思路分析:
- 根据稀疏数组第一行,创建一个二维数组。
- 根据稀疏数组其他行,分别获取有效数组元素的位置和值,放入二维数组对应的位置。
package cn.edu.imau.sparsearray;
public class SparseArray {
public static void main(String[] args) {
// 创建一个原始的二维数组 11 * 11
// 0:没有棋子 1:黑子,2:蓝子
int chessArr1[][] = new int[11][11];
chessArr1[1][2] = 1;
chessArr1[2][3] = 2;
chessArr1[3][4] = 2;
// 输出原始的二维数组
for (int[] row : chessArr1) {
for (int data : row) {
System.out.printf("%d\t", data);
}
System.out.println();
}
// 二维数组转化成稀疏数组
// 1. 遍历二维数组,得到有效数组个数(非零)
int sum = 0;
for (int[] row : chessArr1) {
for (int data : row) {
if (data != 0) {
sum += 1;
}
}
}
// 2. 创建稀疏数组 [sum + 1][3]
int[][] sparseArr = new int[sum + 1][3];
// 3. 将二维数组的行数、列数、有效值个数放入第一行
sparseArr[0][0] = chessArr1.length;
sparseArr[0][1] = chessArr1[0].length;
sparseArr[0][2] = sum;
// 4. 遍历二维数组,将有效值得所在行列及值放入稀疏数组其他行
int k = 1; // 记录稀疏数组目前的行数
int cnt = 0; // 记录找到的有效值
for (int i = 0; i < chessArr1.length; i++) {
for (int j = 0; j < chessArr1[0].length; j++) {
if (chessArr1[i][j] != 0 ) {
// 行
sparseArr[k][0] = i;
// 列
sparseArr[k][1] = j;
// 值
sparseArr[k++][2] = chessArr1[i][j];
cnt++;
}
// 找到所有的有效值,结束循环。
if (cnt == sum) {
break;
}
}
}
System.out.println();
System.out.println("得到的稀疏数组的形式为:");
// 打印稀疏数组
for (int i = 0; i < sparseArr.length; i++) {
System.out.printf("%d\t%d\t%d\t\n", sparseArr[i][0], sparseArr[i][1], sparseArr[i][2]);
}
// 将稀疏数组恢复成原来的二维数组
// 1. 根据稀疏数组第一行创建原始的二维数组
int[][] chessArray2 = new int[sparseArr[0][0]][sparseArr[0][1]];
// 2. 根据稀疏数组其他行将非零数据填入稀疏数组
for (int i = 1; i < sparseArr.length; i++) {
chessArray2[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
}
System.out.println();
System.out.println("稀疏数组恢复为二维数组:");
// 3. 打印原始的二维数组
for (int[] row : chessArray2) {
for (int data : row) {
System.out.printf("%d\t", data);
}
System.out.println();
}
}
}