目录
1 稀疏数组理解
通过新建数组记录原数组行列数、特殊元素个数、每个特殊元素的坐标以及对应特殊元素的值。
2 实现稀疏数组的算法
2.1 算法一
创建稀疏数组,遍历原数组,当找到特殊元素时,特殊元素个数加1,稀疏数组的长度加1,并将特殊元素此时的坐标录入稀疏数组。
2.1.1 算法一分析
2.1.2 算法一代码实现
/**
* 算法一:
* 思路分析:
* 1.创建一个压缩数组初始化第一行,记录行,列,特殊元素总个数。
* 2.循环遍历原数组,当找到特殊元素时,压缩数组扩容,特殊元素个数++,使用特殊元素个数作为下标,
* 记录特殊元素的 行,列,特殊元素的值
* 3. 避免二次遍历原数组
*/
public class Utilities {
public static int[][] arrayCompress(int [][] paraIntArray) {
//1.创建一个压缩数组,
// totalNum 记录原数组总个数, totalDiff 记录特殊元素个数
int totalNum = 0;
int totalDiff = 0;
int [][] compressedArray = new int[1][3];
//2. 遍历原数组,找到默认值不为0的数,记录在压缩数组中
for (int i = 0; i < paraIntArray.length; i++) {
for (int j = 0; j < paraIntArray[i].length; j++) {
totalNum ++;
// 当对应值不为 0 的时候将对应的坐标记录在压缩数组中
if(paraIntArray[i][j] != 0) {
// 特殊元素++
totalDiff ++;
//将压缩数组的容量++
compressedArray = arrayExpansion(compressedArray);
// 使用totalDiff作为下标,记录每个特殊元素的地址
compressedArray[totalDiff][0] = i;
compressedArray[totalDiff][1] = j;
compressedArray[totalDiff][2] = paraIntArray[i][j];
}
}
}
// 3.返回压缩后的数组
compressedArray[0][0] = paraIntArray.length;
compressedArray[0][1] = totalNum / paraIntArray.length;
compressedArray[0][2] =totalDiff;
return compressedArray;
}
/**
* 实现数组扩容方法,完成数组扩容
* 要求
* 1.传入一个元素后,数组容量++
* 方法构成:
* 1.静态方法
* 2.方法名
*/
private static int[][] arrayExpansion(int [][] paraIntArray) {
int tempLength = paraIntArray.length;
int [][] tempIntArray = new int[tempLength + 1][3];
for (int i = 0; i < paraIntArray.length; i++) {
for (int j = 0; j < paraIntArray[i].length; j++) {
tempIntArray[i][j] = paraIntArray[i][j];
}
}
return tempIntArray;
}
}
2.2 算法二
遍历原数组,记录所有元素的个数,再创建稀疏数组,再次遍历原数组,再稀疏数组中记录特殊元素和对应的坐标。
2.2.1 算法二分析
2.2.2 算法二代码实现
class Utilities01 {
// 压缩为稀疏数组
public static int[][] arrayCompress(int[][] paraArray) {
// 定义变量 totalNum 记录原数组总个数, totalDiff 记录特殊元素的总个数
int totalNum = 0;
int totalDiff = 0;
// 1.循环遍历原数组找到特殊元素个数和压缩数组的行列数
for (int i = 0; i < paraArray.length; i++) {
for (int j = 0; j < paraArray[i].length; j++) {
totalNum++;
if (paraArray[i][j] != 0) {
totalDiff++;
}
}
}
// 2. 定义压缩数组(稀疏数组)
int[][] compressedArray = new int[totalDiff + 1][3];
compressedArray[0][0] = paraArray.length;
compressedArray[0][1] = totalNum / paraArray.length;
compressedArray[0][2] = totalDiff;
// 3. 遍历原数组,在压缩数组中记录原数组的坐标
// k 记录特殊元素个数
for (int i = 0, k = 1; i < paraArray.length; i++) {
for (int j = 0; j < paraArray[i].length; j++) {
if (paraArray[i][j] != 0) {
compressedArray[k][0] = i;
compressedArray[k][1] = j;
compressedArray[k][2] = paraArray[i][j];
k++;
}
}
}
return compressedArray;
}
// 恢复为一般数组
public static int[][] RestoreArray(int [][] paraArray) {
// 得到原数组的行列数
int [][] tempArray = new int[paraArray[0][0]][paraArray[0][1]];
// 遍历稀疏数组(从 1 开始),将恢复对应地址的原数组的值。
for (int i = 1; i < paraArray.length; i++) {
tempArray[paraArray[i][0]][paraArray[i][1]] = paraArray[i][2];
}
return tempArray;
}
}
3 测试类
public class Test {
public static void main(String[] args) {
// 0 表示非特殊元素
int [][] testArray = new int[11][11];
testArray[1][2] = 1;
testArray[2][3] = 2;
testArray[3][5] = 1;
System.out.println("测试一");
int [][] arrays = Utilities.arrayCompress(testArray);
for (int i = 0; i < arrays.length; i++) {
for (int j = 0; j < arrays[i].length; j++) {
System.out.print(arrays[i][j] + "\t");
}
System.out.println();
}
System.out.println("测试二");
int [][] arrays01 = Utilities01.arrayCompress(testArray);
for (int i = 0; i < arrays.length; i++) {
for (int j = 0; j < arrays01[i].length; j++) {
System.out.print(arrays01[i][j] + "\t");
}
System.out.println();
}
System.out.println("----恢复为原数组----");
arrays = Utilities01.RestoreArray(arrays);
for (int i = 0; i < arrays.length; i++) {
for (int j = 0; j < arrays[i].length; j++) {
System.out.print(arrays[i][j] + "\t");
}
System.out.println();
}
}
}
3.1 输出效果