数据结构--稀疏数组

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<3mn1
时,使用稀疏数组才能有效的对数据进行压缩。对于上面 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)<St<n+1S1
对于一个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数据结构与算法学习之(稀疏数组)

数据结构与算法—稀疏数组和队列

每天一个数据结构之稀疏数组

每天一个数据结构之稀疏数组

数据结构之二维数组与稀疏数组的转换

Java数据结构—稀疏数组