美文网首页程序员
数据结构--稀疏数组

数据结构--稀疏数组

作者: 乌鸦DD | 来源:发表于2020-04-09 18:32 被阅读0次

概述

稀疏数组也是一种数组(总是二维的),是一种多维数组的数组压缩技术。比如存在一个10 \times 10的数组,但是数组中只有3个元素,如果要存储的话需要占100个位置。因为数组的每个位置的元素都要存储,哪怕是0或者null
\begin{array}{l:} & 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 & \mathbf{5} & 0 & 0 & 0 & 0 & 0 & 0\\ 2 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ 3 & 0 & \mathbf{3} & 0 & 0 & \mathbf{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\\ \end{array}

稀疏数组就是为了解决这个问题的。稀疏数组的第一行存储数组的维度信息以及有效元素数。剩余行存储有效元素所在的坐标和元素的值。如上二维数组,那么采用稀疏数组存储就是:

\begin{array}{l:l:} \text{row}& \text{col} & \text{value} \\ \hline 10 & 10 & 3 \\ 1 & 3 & 5 \\ 3 & 1 & 3 \\ 3 & 4 & 7 \\ \end{array}

稀疏数组的行数是:有效元素数+1;列数是:数组维度+1。如果是一个3维数组,那就需要4列来保存数据,因为有3列要保存元素的坐标。

从上面的例子我们可以看出,稀疏数组存储的数据所占用的位置要比二维数组小很多,上面的10 \times 10的数组占了100个位置,而使用稀疏数组后仅用了16个位置。

什么情况下才可以用稀疏数组

然而稀疏数组并不总是好的,从上面的例子中我们也看出来了,稀疏数组只适合于有效数据少,但是数组较大的情况。假设一个二维数组行是m列是nt个有效数据,那么稀疏数组的行数就是t+1,列数是3,所以只有在
3(t+1) < mn; \Longrightarrow t < \frac{mn}{3} - 1
时,使用稀疏数组才能有效的对数据进行压缩。对于上面10 \times 10的数组就是32,如果超过32个有效元素,使用稀疏数组反而会增加开销。

那么推广到多维数组,假设n维数组可以存储S个元素,数组中有t个有效元素。那么稀疏数组的行数就是t+1,列数是n+1。只有在
(t+1)(n+1) < S \Longrightarrow t < \frac{S}{n+1} - 1
对于一个3维可存放1000个元素的数组,只有当有效元素小于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] = i;
                    sparseArr[index][1] = j;
                    sparseArr[index][2] = num;
                    index++;
                }
            }
        }
        return sparseArr;
    }

    /**
     * 将一个稀疏数组转为二维数组
     * @param sparseArr 稀疏数组,这里稀疏数组需要是一个二维数组的稀疏数组。
     * @return 还原后的二维数组
     */
    public int[][] parse(int[][] sparseArr) {
        int row = sparseArr[0][0],
                col = sparseArr[0][1],
                nums =  sparseArr[0][2];

        int[][] arr = new int[row][col];
        for (int i = 1; i <= nums; i++) {
            int[] ints = sparseArr[i];
            arr[ints[0]][ints[1]] = ints[2];
        }
        return arr;
    }

    /**
     * 测试一下
     * @param args
     */
    public static void main(String[] args) {
        SparseArray sparseArray = new SparseArray();
        int[][] arrs = new int[11][11];
        arrs[2][3] = 10;
        arrs[3][6] = 20;
        int[][] sparseArr = sparseArray.toSparse(arrs);
        System.out.println(sparseArr);
        int[][] sourceArr = sparseArray.parse(sparseArr);
        System.out.println(sourceArr);
    }

}

对于n \times n的二维数组,toSparse()的时间复杂度为O(2n^2) = O(n^2)(如果不知道这里为什么等于O(n^2)可以看看我个人博客上关于算法复杂度的文章)。parse()方法的时间复杂度是O(n),这个n是有效元素数(O(n+1) = O(n)

应用

如棋盘的保存。围棋或者五子棋,要把棋盘上落子的信息保存起来。

相关文章

  • 数据结构--稀疏数组

    概述 稀疏数组也是一种数组(总是二维的),是一种多维数组的数组压缩技术。比如存在一个的数组,但是数组中只有3个元素...

  • 数据结构之 稀疏数组

    作用 当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。 实现思路 1)记录数组一...

  • 数据结构入门教程-队列

    上节我们简单的了解了什么是稀疏数组以及通过一个案例来简单分析它,关于它的更多详情请移驾数据结构入门教程-稀疏数组,...

  • 数据结构002之稀疏数组

    什么是稀疏数组? 稀疏数组可以看做是对普通数组的压缩,普通数组是指无效数据量远大于有效数据量的数组,为什么要进行压...

  • 重学数据结构 --- 分类+稀疏数组

    一、数据结构的分类 1. 数据结构两大类 线性结构和非线性结构 1) 线性结构 线性结构是最常见的数据结构,特点是...

  • java数据结构之稀疏数组

    今天学习了数组中的一种-叫做稀疏数组。什么叫稀疏数组呢?如果一个数组(包括多维数组)中的大部分元素为0,或者为同一...

  • 数据结构-4.稀疏数组

    1. 当一个数组中大部分元素为 0,或者为同一个值时,可以使用稀疏数组来保存该数组 处理方法: 记录数组一共有多少...

  • 稀疏数组

    1.稀疏数组 1.1创建一个指定长度的稀疏数组 new创建var a = new Array();>>(3)[em...

  • 稀疏数组

    当数组中的大部分元素为0,或者同一值时,可以使用稀疏数组来存储该数组,使用稀疏矩阵可以节约存储空间稀疏数组的处理方...

  • 稀疏数组

    1、稀疏算法的基本介绍当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。从而减少计...

网友评论

    本文标题:数据结构--稀疏数组

    本文链接:https://www.haomeiwen.com/subject/btkhmhtx.html