数据结构之稀疏数组
1、 什么是稀疏数组?
稀疏数组是对多维数组进行压缩的技术。当一个数组中大部分元素为空或者为同一个值的时候,可以使用稀疏数组来保存该数组。比如在一个6×7的二维数组当中(如下图),实际只有7个有效的元素,如果不经过处理,全部存储的话,需要占42个位置。而实际只有7个有效数据,造成了不必要的存储开支。
使用稀疏数组就是为了解决上面问题的,稀疏数组是一个多维数组,有N行N列
,其中行数是:有效元素数+1,列数是:数组维度+1。
上面图示的二维数组,用稀疏数组表示如下:
说明:第一行第一列是:原数组的行数,第一行第二列是:原数组的列数,第一行第三列是:原数组有效元素数。
2、稀疏数组适用的场景
稀疏数组只适合于有效数据少,但是数组较大的情况。假设一个二维数组行是m列是n 有 t个有效数据,那么稀疏数组的行数就是t+1,列数是3,所以只有在
3
(
t
+
1
)
<
m
n
=
>
t
<
m
n
3
−
1
3(t+1)<mn=> t<\frac {mn} {3}-1
3(t+1)<mn=>t<3mn−1
时,使用稀疏数组才能有效的对数据进行压缩。对于上面6✖7的数组如果超过12个有效元素,使用稀疏数组反而会增加开销。
那么推广到多维数组,假设n维数组可以存储S个元素,数组中有t个有效元素。那么稀疏数组的行数就是t+1,列数是n+1。只有在
(
t
+
1
)
(
n
+
1
)
<
S
=
>
t
<
S
n
+
1
−
1
(t+1)(n+1)<S=> t<\frac {S} {n+1}-1
(t+1)(n+1)<S=>t<n+1S−1
对于一个3维可存放1000个元素的数组,只有当有效元素小于249时,适用稀疏数组才能起到节省空间的作用。
3、代码实现
基于java实现,二维数据转稀疏数组,稀疏数组还原为二维数组
/**
* 二维数据转化为稀疏数组
* @param array
* @return
*/
public static int[][] toSparseArray(int[][] array){
int sum=0;//数组有有效元素数
for (int i=0;i<array.length;i++) {
for (int j = 0; j < array[i].length; j++) {
if (array[i][j] != 0) {
sum++;
}
}
}
//初始化一个稀疏数组,列数为原数组的有效数据+1
int sparseArray[][]=new int[sum+1][3];
//第一行第一列是:原数组的行数,
// 第一行第二列是:原数组的列数,
// 第一行第三列是:原数组有效元素数。
sparseArray[0][0]=array.length;
sparseArray[0][1]=array[0].length;
sparseArray[0][2]=sum;
//把有效数据存储到稀疏数组中
int count=0;
for (int i=0;i<array.length;i++) {
for (int j = 0; j < array[i].length; j++) {
if (array[i][j] != 0) {
count++;
//第N行第一列是:原数组的数据所在行,
// 第N行第二列是:原数组的数据所在列,
// 第N行第三列是:原数组的数据。
sparseArray[count][0]=i;
sparseArray[count][1]=j;
sparseArray[count][2]=array[i][j];
}
}
}
return sparseArray;
}
/**
* 稀疏数组还原为二维数组
* @param sparseArray
* @return
*/
public static int[][] sparseArrayToArray(int[][] sparseArray){
//数组行数
int rows=sparseArray[0][0];
//数组列数
int cols=sparseArray[0][1];
//初始化二维数组
int array[][]=new int[rows][cols];
for (int i = 1; i < sparseArray.length; i++) {
array[sparseArray[i][0]][sparseArray[i][1]]=sparseArray[i][2];
}
return array;
}
/**
*测试
* @param args
*/
public static void main(String[] args) {
//创建原始二位数组
int classArray[][]=new int[11][11];
classArray[1][1]=1;
classArray[3][2]=2;
System.out.println("==============原始数组================");
for (int i=0;i<classArray.length;i++){
for (int j=0;j<classArray[i].length;j++){
System.out.print(classArray[i][j]);
System.out.print(" ");
}
System.out.println("");
}
System.out.println("==============稀疏数组================");
int[][] sparseArray = toSparseArray(classArray);
for (int[] arr:sparseArray){
for (int v:arr){
System.out.print(v);
System.out.print(" ");
}
System.out.println("");
}
System.out.println("==============稀疏还原到二维数组================");
int[][] array = sparseArrayToArray(sparseArray);
for (int i=0;i<array.length;i++) {
for (int j = 0; j < array[i].length; j++) {
System.out.print(array[i][j]);
System.out.print(" ");
}
System.out.println(" ");
}
}
参考:https://www.jianshu.com/p/8693b7108a62