稀疏数组
一、什么是稀疏数组?
当一个数组中大部分元素是0,或为同一个值的时候,可以使用稀疏数组来保存数组。它是一个十分有效的存储结构,便于节省存储空间。
二、稀疏数组怎么组成?
稀疏数组的样子为固定的三列,第一列记录原来的二维数组总的行数,列表,多少个值 ,行数根据数据的多少来决定
三、应用场景
这里有个需求,通过二维数组来模拟棋盘状态,显然此时数组中大部分元素为零,为了节省空间,可以考虑使用稀疏数组。
二维数组转稀疏数组的思路是:
1、记录数组一共有几行几列,有多少不同的值。如上图所示,二维数组为11*11,共有两个有效数据,1和2。
2、创建稀疏数组int sparseArr[3][3],第一行为二维数组的行数、列数、有效值个数。后面两行记录的是有效值的位置和它的值。
稀疏数组转二维数组的思路是:
1、先读取稀疏数组的第一行,创建11*11的二维数组。
2、依次遍历之后各行,将有效值填充进二维数组。
四、代码实现
package com.loyu.dataStructure.sparseArray;
/**
* 稀疏数组
* @className : SparseArrayDemo
* @Author : YuLongJun
* @Version : 1.0
*/
public class SparseArrayDemo {
public static void main(String[] args) {
// 创建一个
int[][] test = new int[11][11];
test[3][3]=2;
test[5][6]=6;
test[6][8]=7;
test[8][8]=21;
//遍历打印
traverse(toSparseArray(test));
}
/**
* 原始二维数组转化为稀疏数组
* @param original
* @return
*/
public static int[][] toSparseArray(int[][] original){
// 定义稀疏数组,就必须计算出稀疏数组的行和列的长度,根据原始的二维数组计算
// 第一步 计算原始数组的不为0的有效值
int effectiveValue=0;
//原来数组列
int oldColumn=0;
//遍历原始数组
for(int[] var01:original){
for(int var02:var01){
//不为0的情况
if(var02!=0){
//effectiveValue加一
effectiveValue++;
}
}
oldColumn++;
}
//定义稀疏数组,内存中开辟空间,3列是固定的,然后行数是值+1,加一是因为第一行需要记录总的数组信息
int[][] sparseArray = new int[effectiveValue+1][3];
//添加第一行
//第一行第一列表示原来二维数组总共多少行
sparseArray[0][0]=original.length;
//第一行第二列表示原来二维数组总共多少列
sparseArray[0][1]=oldColumn;
//第一行第三列表示原来二维数组总共多少有效的值
sparseArray[0][2]=effectiveValue;
//接下来的值都是遍历添加的
//count用来记录稀疏数组添加到哪一行了,count初始值为1,因为0行数组是添加了的,记录整体信息用的
int count=1;
for(int var01=0;var01<original.length;var01++){
for(int var02=0;var02<oldColumn;var02++) {
//当前数组值不为0的情况
if(original[var01][var02]!=0){
//记录目前的行数
sparseArray[count][0]=var01;
//记录目前的列数
sparseArray[count][1]=var02;
//记录目前真实值
sparseArray[count][2]=original[var01][var02];
//count加1计数
count++;
}
}
}
return sparseArray;
}
/**
* 遍历数组
* @param array
* @param
*/
public static void traverse(int[][] array){
for(int[] var01 : array){
for(int var02:var01){
System.out.print(var02+" ");
}
System.out.println();
}
}
}
原来的二维数组
压缩后的数组
五、稀疏数组的优劣势
优势:大大缩小了内存的空间;
- 避免了基本数据类型的装箱操作
- 不需要额外的结构体,单个元素的存储成本更低
- 数据量小的情况下,随机访问的效率更高
劣势:增加了转化成本
- 插入操作需要复制数组,增删效率降低
- 数据量巨大时,查询效率也会明显下降
六、稀疏数组的适用场景
1、大量的无用数据占据内存或者空值
2、插入删除数组值的情况比较多的时候,不适用,查询比较多,增删比较少的时候适用
- 数据量小的情况下,随机访问的效率更高
劣势:增加了转化成本
- 插入操作需要复制数组,增删效率降低
- 数据量巨大时,查询效率也会明显下降
六、稀疏数组的适用场景
1、大量的无用数据占据内存或者空值
2、插入删除数组值的情况比较多的时候,不适用,查询比较多,增删比较少的时候适用