稀疏数组
稀疏数组就是数组中大部分的内容值都未被使用(或都为0),在数组中仅有少部分的空间使用。因此会造成内存空间的浪费。
为了节省内存空间,并且不影响数组中原有的内容值,我们可以采用一种压缩的方式来表示稀疏数组的内容。
算法效果举例
假设有一个97的数组:
在此数组中,共有63个空间,但却只使用了5个元素,造成58个元素空间的浪费。
以下我们就使用稀疏数组重新来定义这个数组:
第一行的三个元素表示原数组的行数、列数、使用个数
第二行开始,每行的三个元素分别代表一个元素在原数组的行数、列数、元素的值。
a[1][1]=3
a[3][0]=1
…
这样压缩后,原本需要63的数组,使用压缩后,只需要声明大小为63的数组,仅需要18个存储空间。
代码实现
package demo;
public class ArraryCompress {
public static void main(String[] args) {
//一般的做法,浪费内存空间,读数据的时候效率高
long[][] arr = new long[9][7];
arr[1][1] = 3;
arr[3][0] = 1;
arr[3][1] = 4;
arr[4][2] = 7;
arr[5][5] = 5;
//一般这种做法在输出演示的时候,有效率一些、
for(int i = 0;i<arr.length;i++){
for(int j = 0;j<arr[i].length;j++){
System.out.print(arr[i][j]+ " ");
}
System.out.println();
}
//对稀疏数组进行压缩
Node[] nodes = new Node[6];
nodes[0] = new Node(9,7,5);
nodes[1] = new Node(1,1,3);
nodes[2] = new Node(3,0,1);
nodes[3] = new Node(3,1,4);
nodes[4] = new Node(4,2,7);
nodes[5] = new Node(5,5,5);
System.out.println("------------------对压缩后的数组进行读操作,显示出原数组----------------");
for(int i=0;i<nodes[0].getRow();i++){
for(int j=0; j<nodes[0].getCol();j++){
//判断当前(i,j)坐标的位置有没有有效内容值,有就输出,没有就输出0
int k;
for(k=1;k<nodes.length;k++){
if(nodes[k].getRow()==i && nodes[k].getCol()==j){
break;
}
}
if(k<nodes.length){//证明这里存在有效内容值
System.out.print(nodes[k].getVal() + " ");
}else{
System.out.print(0 + " ");
}
}
System.out.println();
}
/**
* 根据压缩内容恢复数组
*/
System.out.println("------------------尝试恢复数组----------------");
long[][] arr1 = new long[nodes[0].getRow()][nodes[0].getCol()];
for(int i=1;i<nodes.length;i++){
arr1[nodes[i].getRow()][nodes[i].getCol()] = nodes[i].getVal();
}
//打印数组
for(int i = 0;i<arr1.length;i++){
for(int j = 0;j<arr1[i].length;j++){
System.out.print(arr1[i][j]+ " ");
}
System.out.println();
}
}
}
class Node{
private int row; //行数
private int col; //列数
private long val; //使用个数
//用构造方法对三个属性初始化
public Node(int row, int col, int val){
this.row = row;
this.col = col;
this.val = val;
}
public int getRow(){
return row;
}
public int getCol(){
return col;
}
public long getVal(){
return val;
}
}