数据结构之稀疏数组

一、定义

首先是关于稀疏数组,什么是稀疏数组?在数学中有个叫稀疏矩阵的东西,稀疏矩阵的定义是在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵。
延申到数据结构中的稀疏数组时,如果一个数组中元素为0的数目远远大于非0元素的数目,那么将这个数组进行压缩之后得到的一个新的数组就是稀疏数组。再到实际应用中,如果一个数组中我们不想要的元素(可以为0,也可以不为0)远远大于我们想要的元素,那么我们也可以将这个数组进行压缩保存之后得到一个稀疏数组。

二、稀疏数组存在的意义

在上面中提到稀疏数组是由另一个数组进行压缩得到的,那么为什么要原本的数组进行压缩呢?

理由是原本的数组存在着大量无用的数组,真正有用的数据较少,如果用普通的数组进行保存,在数据序列化存储在磁盘中时,进行IO的效率会降低。而使用稀疏数组可以节省存储空间,避免了不必要的资源的浪费,提高了IO效率。

三、压缩存储的方式

1、普通的存储
第一行分别为原数组的行、列、有效数据个数
第二行之后分别为有效数据所在的行、列、有效数据值
如:

 rows cols  n
 r1   c1    data1
 ......
 rn   cn    datan

举个例子():
原数组为:

              0 0 0 0 0 0 0 0 0 0 0
              0 0 1 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 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 4 0 0 0 0 0 0 0 0
              0 0 0 0 0 0 0 0 0 0 0
              0 0 3 0 0 0 0 0 0 0 0

进行压缩存储后得到的稀疏数组为:

              11 11 4
              1  2  1  
              2  4  2  
              8  2  4  
              10  2  3 

代码以及相关注释如下:

/**
 * 稀疏数组
 * @author lhq
 *
 */
public class SparseArray {
	public static void main(String[] args) {
		//有效数据个数
		int sum=0;
		//初始化数组
		int array[][]= new int[11][11];
		//有效数据
		array[1][2]=1;
		array[2][4]=2;
		array[10][2]=3;
		array[8][2]=4;
		//统计有效数据个数
		System.out.println("初始二维数组为:");
		for(int i=0;i<array.length;i++) {
			for(int j=0;j<array[i].length;j++) {
				System.out.print(array[i][j]+"  ");
				if(array[i][j]!=0)
					sum++;
			}
			System.out.println();
		}
		//定义稀疏数组
		int sparseArray[][]=new int[sum+1][3];
		//记录行数
		sparseArray[0][0] = array.length;
		//记录列数
		sparseArray[0][1] = array[0].length;
		//记录有效数据个数
		sparseArray[0][2] = sum;
		//标识第几个
		int count=1;
		//记录对应数据
		for(int i=0;i<array.length;i++) {
			for(int j=0;j<array[i].length;j++)
				if(array[i][j]!=0) {
					sparseArray[count][0]=i;
					sparseArray[count][1]=j;
					sparseArray[count][2]=array[i][j];
					count++;
				}
		}
		System.out.println("进行压缩存储之后的稀疏数组为:");
		//输出稀疏数组
		for(int i=0;i<sparseArray.length;i++) {
			for(int j=0;j<sparseArray[i].length;j++)
				System.out.print(sparseArray[i][j]+"  ");
			System.out.println();
					
		}
	}
}

然后就是从稀疏数组转换为普通的二维数组的过程,稀疏数组第一行的前两列就是普通二维数组的行列,第三列就是需要遍历稀疏数组的次数(遍历从稀疏数组第二行开始),然后即可还原初始的二维数组。代码如下:

public static int[][] SparseToCommomArray(int [][]sparseArray) {
		//初始化数组
		int[][] commonArray = new int[sparseArray[0][0]][sparseArray[0][1]];
		//将稀疏数组中存储的数据取出并在找到对应的位置
		for(int i=0;i<sparseArray[0][2];i++) {
			commonArray[sparseArray[i+1][0]][sparseArray[i+1][1]]=sparseArray[i+1][2];
		}
		//输出转化后的二维数组
		for(int i=0;i<commonArray.length;i++) {
			for(int j=0;j<commonArray[i].length;j++) {
				System.out.print(commonArray[i][j]+"  ");
			}
			System.out.println();
		}
		return commonArray;
	}

最后附上整个完整的代码:

/**
 * 稀疏数组
 * @author lhq
 *
 */
public class SparseArray {
	public static void main(String[] args) {
		//有效数据个数
		int sum=0;
		//初始化数组
		int array[][]= new int[11][11];
		//有效数据
		array[1][2]=1;
		array[2][4]=2;
		array[10][2]=3;
		array[8][2]=4;
		//统计有效数据个数
		System.out.println("初始二维数组为:");
		for(int i=0;i<array.length;i++) {
			for(int j=0;j<array[i].length;j++) {
				System.out.print(array[i][j]+"  ");
				if(array[i][j]!=0)
					sum++;
			}
			System.out.println();
		}
		//定义稀疏数组
		int sparseArray[][]=new int[sum+1][3];
		//记录行数
		sparseArray[0][0] = array.length;
		//记录列数
		sparseArray[0][1] = array[0].length;
		//记录有效数据个数
		sparseArray[0][2] = sum;
		//标识第几个
		int count=1;
		//记录对应数据
		for(int i=0;i<array.length;i++) {
			for(int j=0;j<array[i].length;j++)
				if(array[i][j]!=0) {
					sparseArray[count][0]=i;
					sparseArray[count][1]=j;
					sparseArray[count][2]=array[i][j];
					count++;
				}
		}
		System.out.println("进行压缩存储之后的稀疏数组为:");
		//输出稀疏数组
		for(int i=0;i<sparseArray.length;i++) {
			for(int j=0;j<sparseArray[i].length;j++)
				System.out.print(sparseArray[i][j]+"  ");
			System.out.println();
					
		}
		System.out.println("将稀疏数组转化为初始二维数组为:");
		SparseToCommomArray(sparseArray);
	}
	
	public static int[][] SparseToCommomArray(int [][]sparseArray) {
		//初始化数组
		int[][] commonArray = new int[sparseArray[0][0]][sparseArray[0][1]];
		//将稀疏数组中存储的数据取出并在找到对应的位置
		for(int i=0;i<sparseArray[0][2];i++) {
			commonArray[sparseArray[i+1][0]][sparseArray[i+1][1]]=sparseArray[i+1][2];
		}
		//输出转化后的二维数组
		for(int i=0;i<commonArray.length;i++) {
			for(int j=0;j<commonArray[i].length;j++) {
				System.out.print(commonArray[i][j]+"  ");
			}
			System.out.println();
		}
		return commonArray;
	}
}
以上就是本人对稀疏数组学习一个大概的总结,从一个普通的二维数组压缩转化为稀疏数组还有其他的压缩方式,可以以链表的形式压缩存储,在这里就不多说了。
以上内容纯属为个人总结,如有错误之处以及需改进的地方欢迎指出。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值