一、稀疏数组概念
在我们存储有大量重复元素值的二维数组时,如果使用一般的二维数组可能会有大量重复元素,这样就会浪费空间,这个时候我们就可以用稀疏数组来进行压缩。
例如:下图是一个普通的二维数组
这是一个8×8的二维数组,但是他的绝大部分都是0,也就是绝大部分都是相同的数字,这样我们存储的时候就比较的占用空间。也许这个看起来也不少那么的难以让人接受,但是如果是100×100,1000×1000那么就会十分难处理。
如果把这个用稀疏数组来表示的话。如下图
对比非常明显,这么大的二维数组用稀疏数组来表示只需要这么几行。
二、稀疏数组如何表示
就按照上述的例子来讲,稀疏数组的第一行,也就是 8 8 3。
第一个8代表的是它所表示的二维数组的行数,一共是8行。
第二个8代表的是它所表示的二维数组的列数,一共是8列。
第三个数字3表示的是,在原二维数组中,除去了大量的重复元素之外,还有多少个元素的总个数。也就是上图二维数组中的1 2 2,总个数为3个。
除去稀疏数组的第一行,下面的每一行都是在表示一个元素的位置与值第一个数字是此元素所在原二维数组中的行数,第二个数字是所在原二维数组中的列数,第三个数字就是这个元素的值。
例如:
这里的1 2 1就代表有一个值为1的元素,在原二维数组中的位置是第2行第3列(下标从0开始),后面的每一行都以此类推。
三、代码实现
1.创建一个原二维数组
//创建原二维数组chess1
int chess1[][] = new int[8][8];
chess1[1][2]=1;
chess1[2][3]=2;
chess1[3][5]=2;
//进行遍历
for (int[] row : chess1){
for (int data : row){
System.out.printf("%d\t",data);
}
System.out.println();
}
运行结果如最上面的那张图。
1.二维数组→稀疏数组
思路:将二维数组转化为稀疏数组,稀疏数组的第一行一定是原二维数组的行数、列数和额外元素总和sum,所以一地步就是要求出sum。
//计算除去重复元素外的元素总数
int sum=0;
for (int[] row : chess1){
for (int data : row){
if (data != 0)
sum=sum+1;
}
}
知道了sum只有,稀疏数组的第一行就可以写好了,然后就是后面的元素对应的存储,可以用最简单的遍历方法将非0的元素提取出来放入稀疏数组。
//创建稀疏数组
int count = 0;
int sparse[][] = new int[sum+1][3];
sparse[0][0]=8;
sparse[0][1]=8;
sparse[0][2]=sum;
for (int i = 0; i <8 ; i++) {
for (int j = 0; j <8 ; j++) {
if (chess1[i][j] != 0){
count++;
sparse[count][0]=i;
sparse[count][1]=j;
sparse[count][2]=chess1[i][j];
}
}
}
//进行遍历
for (int[] row : sparse){
for (int data : row){
System.out.printf("%d\t",data);
}
System.out.println();
}
运行结果如上图的稀疏数组列图
1.稀疏数组→二维数组
思路:要将稀疏数组还原为二维数组就很简单,只需要从稀疏数组的第一行得知原二维数组的行数与列数,然后对稀疏数组遍历,赋值到相对应的二维数组中。
//还原二维数组
int chess2[][] = new int [sparse[0][0]][sparse[0][1]];
for (int i = 1; i <sparse.length ; i++) {
chess2[sparse[i][0]][sparse[i][1]]=sparse[i][2];
}
//遍历
for (int[] row : chess2){
for (int data : row){
System.out.printf("%d\t",data);
}
System.out.println();
}
即可将稀疏数组转回二维数组。