稀疏数组学习
稀疏数组(Sparse Array) 是一种用于压缩存储大量默认值(通常是 0)的数组的数据结构。它通过只存储非默认值的元素及其位置来节省空间。稀疏数组常用于存储矩阵或二维数组,尤其是当数组中大部分元素为默认值时。
稀疏数组的核心思想
普通数组的问题:
如果一个二维数组中有大量重复的默认值(如 0),存储这些值会浪费空间。
稀疏数组的解决方案:
只存储非默认值的元素及其位置。
使用一个三元组 (行, 列, 值) 来表示每个非默认值。
稀疏数组的结构
稀疏数组通常由两部分组成:
第一行:
存储原始数组的行数、列数以及非默认值的个数。
例如:[行数, 列数, 非默认值个数]。
后续行:
每一行存储一个非默认值的三元组 (行, 列, 值)。
package com.jianstudy.array;
public class ArrayDemo11 {
public static void main(String[] args) {
//稀疏数组学习
//原始数组
int[][] array1 = {
{0,0,0,2,0},
{0,0,3,0,0},
{1,0,0,5,0},
{0,4,0,0,0}
};
//获取原始数组有效值的个数
int result = 0;//定义一个result存放有效值的个数
for(int i =0;i< array1.length;i++){
for(int j =0;j<array1[0].length;j++){
if(array1[i][j]!=0){//判断如果对应某行某列的元素不等于0(即有效值)就让result自增
result ++;
}
}
}
System.out.println("原始数组有效值有"+result+"个"); //原始数组有效值有5个
//创建一个数组存放稀疏数组
int[][] array2 = new int[result+1][3]; //稀疏数组的长度是[5+1][3] 6行3列
/*
稀疏数组的一层是行数,有效值的个数+1(多一行表示头部信息 用来存放 行,列,有效值)
稀疏数组的二层是列数固定3 (1列存放的行,2列存放的列,3列存放的有效值)
*/
//用二维数组的长度来表示稀疏数组的头部 行 信息
array2[0][0]= array1.length;//初始化 把原始数组行的长度 赋给 稀疏数组的第一行第一列
//因为原始数组是规则的二维数组,所以每一组二维数组的内层一维数组长度是一样的所以可以随便取一组来获取内层一维数组的长度
//用内层的一维数组的长度来表示稀疏数组的头部 列 信息
array2[0][1]= array1[0].length;//初始化 把原始数组列的长度 赋给 稀疏数组的第一行第二列
//用result表示稀疏数组的头部有效值信息
array2[0][2]=result;//初始化 把获得有效值的个数 赋给 稀疏数组的第一行第三列
/*
得到头部信息(第一行)
行 列 有效值
*/
//填充稀疏数组
//第一次循环会把头部信息遍历出来,后续得到的都是有效值元素的行列坐标以及有效元素本身的值
int count =0;//计数 稀疏数组的有效值行数
for(int i=0 ;i< array1.length ;i++){
for(int j=0 ;j<array1[0].length;j++){
if(array1[i][j]!=0){//如果原始数组的某个值不为0(即有效值)执行以下代码
count++;
array2[count][0] = i;//稀疏数组有效值的行坐标
array2[count][1] = j;//稀疏数组有效值的列坐标
array2[count][2] = array1[i][j];//稀疏数组的有效值
}
}
}
//输出稀疏数组
System.out.println("输出稀疏数组");
for(int i = 0;i<array2.length;i++){//因为稀疏数组的列数是固定的所以只需要循环行数i
System.out.println( array2[i][0]+" "
+ array2[i][1]+" "
+ array2[i][2]+" ");
/*
此时的稀疏数组
array2 =[5+1][3] 6行3列
0 1 2
0头部信息 行4 列5 有效值5
1 0 3 2
2 1 2 3
3 2 0 1
4 2 3 5
5 3 1 4
array2 = {{4 5 5},
{0 3 2},
{1 2 3},
{2 0 1},
{2 3 5},
{3 1 4}
}
*/
}
//还原稀疏数组
//1.读取稀疏数组
//稀疏数组的头部行列信息就是还原数组的外内层元素。且隐性的初始化还原数组array3的各个元素
int[][] array3 = new int[array2[0][0]][array2[0][1]];//array2[0][0]=4 array2[0][1]=5
/* 头部信息 行4 列5
int[][] array3 = new int[4][5];
array3[0][0]=0;
...
...
...
array3[3][4]=0;
4*5=20个元素全部被隐性的初始化
*/
//2.给其中的元素还原他的值。
for (int i = 1; i < array2.length; i++) {//要从第二行开始,第一行是头部信息i=1就是第二行开始 如果i=0就会读到头部信息
/*
0 1行 头部信息 行4 列5 有效值5
1 2行 0 3 2 1 2行 0 3 2
2 3行 1 2 3 2 3行 1 2 3
3 4行 2 0 1 --------> 3 4行 2 0 1
4 5行 2 3 5 4 5行 2 3 5
5 6行 3 1 4 5 6行 3 1 4
*/
//这里可以看成初始化array3的元素。还原数组接收稀疏数组有效值,匹配的是稀疏数组有效值的行列
array3[array2[i][0]][array2[i][1]]=array2[i][2];//稀疏数组的有效值,赋给还原数组的对应项
/*
从
{{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}}
{{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}}
{{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}}
{{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}}
{{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}}
到
{{0,0,0,2,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}}
{{0,0,0,2,0},{0,0,3,0,0},{0,0,0,0,0},{0,0,0,0,0}}
{{0,0,0,2,0},{0,0,3,0,0},{1,0,0,0,0},{0,0,0,0,0}}
{{0,0,0,2,0},{0,0,3,0,0},{1,0,0,5,0},{0,0,0,0,0}}
{{0,0,0,2,0},{0,0,3,0,0},{1,0,0,5,0},{0,4,0,0,0}}
*/
}
System.out.println("=============");
//3.使用for each循环打印还原后的稀疏数组
for(int[] a:array3){
for(int b:a){
System.out.print(b+" ");
}
System.out.println();
}
}
}