数据结构--稀疏数组
Posted 大扑棱蛾子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构--稀疏数组相关的知识,希望对你有一定的参考价值。
概述
稀疏数组也是一种数组(总是二维的),是一种多维数组的数组压缩技术。比如存在一个
10
×
10
10 \\times 10
10×10的数组,但是数组中只有3个元素,如果要存储的话需要占100个位置。因为数组的每个位置的元素都要存储,哪怕是0
或者null
。
0
1
2
3
4
5
6
7
8
9
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
5
0
0
0
0
0
0
2
0
0
0
0
0
0
0
0
0
0
3
0
3
0
0
7
0
0
0
0
0
4
0
0
0
0
0
0
0
0
0
0
5
0
0
0
0
0
0
0
0
0
0
6
0
0
0
0
0
0
0
0
0
0
7
0
0
0
0
0
0
0
0
0
0
8
0
0
0
0
0
0
0
0
0
0
9
0
0
0
0
0
0
0
0
0
0
\\beginarrayl: & 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9\\\\ \\hline 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\\\ 1 & 0 & 0 & 0 & \\colorred\\mathbf5 & 0 & 0 & 0 & 0 & 0 & 0\\\\ 2 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\\\ 3 & 0 & \\colorred\\mathbf3 & 0 & 0 & \\colorred\\mathbf7 & 0 & 0 & 0 & 0 & 0\\\\ 4 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\\\ 5 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\\\ 6 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\\\ 7 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\\\ 8 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\\\ 9 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\\\ \\endarray
012345678900000000000100030000002000000000030500000000400070000005000000000060000000000700000000008000000000090000000000
稀疏数组就是为了解决这个问题的。稀疏数组的第一行存储数组的维度信息以及有效元素数。剩余行存储有效元素所在的坐标和元素的值。如上二维数组,那么采用稀疏数组存储就是:
row col value 10 10 3 1 3 5 3 1 3 3 4 7 \\beginarrayl:l: \\textrow& \\textcol & \\textvalue \\\\ \\hline 10 & 10 & 3 \\\\ 1 & 3 & 5 \\\\ 3 & 1 & 3 \\\\ 3 & 4 & 7 \\\\ \\endarray row10133col10314value3537
稀疏数组的行数是:有效元素数+1;列数是:数组维度+1。如果是一个3维数组,那就需要4列来保存数据,因为有3列要保存元素的坐标。
从上面的例子我们可以看出,稀疏数组存储的数据所占用的位置要比二维数组小很多,上面的 10 × 10 10 \\times 10 10×10的数组占了100个位置,而使用稀疏数组后仅用了16个位置。
什么情况下才可以用稀疏数组
然而稀疏数组并不总是好的,从上面的例子中我们也看出来了,稀疏数组只适合于有效数据少,但是数组较大的情况。假设一个二维数组行是
m
m
m列是
n
n
n 有
t
t
t个有效数据,那么稀疏数组的行数就是
t
+
1
t+1
t+1,列数是3,所以只有在
3
(
t
+
1
)
<
m
n
;
⟹
t
<
m
n
3
−
1
3(t+1) < mn; \\Longrightarrow t < \\fracmn3 - 1
3(t+1)<mn;⟹t<3mn−1
时,使用稀疏数组才能有效的对数据进行压缩。对于上面
10
×
10
10 \\times 10
10×10的数组就是32,如果超过32个有效元素,使用稀疏数组反而会增加开销。
那么推广到多维数组,假设
n
n
n维数组可以存储
S
S
S个元素,数组中有
t
t
t个有效元素。那么稀疏数组的行数就是
t
+
1
t+1
t+1,列数是
n
+
1
n+1
n+1。只有在
(
t
+
1
)
(
n
+
1
)
<
S
⟹
t
<
S
n
+
1
−
1
(t+1)(n+1) < S \\Longrightarrow t < \\fracSn+1 - 1
(t+1)(n+1)<S⟹t<n+1S−1
对于一个3维可存放1000个元素的数组,只有当有效元素小于
249
249
249时,适用稀疏数组才能起到节省空间的作用。
实现
以下列出Java中二维稀疏数组的实现。
package com.codestd.study.ds;
/**
* 稀疏数组
*
* @author jaune
* @since 1.0.0
*/
public class SparseArray
/**
* 将一个二维数组转成稀疏数组
* @param arrs 二维数组
* @return 稀疏数组
*/
public int[][] toSparse(int[][] arrs)
//arrs.length;
int row = arrs.length, col = arrs[0].length, nums = 0;
for (int[] arr : arrs)
for (int i : arr)
if (i != 0)
nums++;
int[][] sparseArr = new int[nums + 1][3];
sparseArr[0][0] = row;
sparseArr[0][1] = col;
sparseArr[0][2] = nums;
int index = 1;
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
int num = arrs[i][j];
if (num != 0)
sparseArr[index][0数据结构与算法学习之(稀疏数组)