编程语言
首页 > 编程语言> > 数据结构与算法-稀疏数组详解

数据结构与算法-稀疏数组详解

作者:互联网

1.背景

1.1.假设让你开发一个五子棋,你会如何存储棋盘

1.2.数组保存棋盘

假设:

0-白表示空白位置(即没有走过的位置)

1-表示白棋

2-表示黑棋

如果是数组保存棋盘,你会发现很多数据都是零,如下图:

 

上面,我们通过二维数组的方法,将棋盘数据保存在了一个二维数组中,整个数组我们用了 16 × 16(共 256)个点来保存数据,其中有 254 个点都是空的。

实际来说,我们只需要将有价值的黑白子保存起来即可,因为只要我们知道黑白子数据,以及棋盘的大小,那么这 254 个空点是可以不用进行保存的。

把这样没有价值的数据起来,不但会浪费存储空间的大小,如果写入到磁盘中,还会增大 IO 的读写量,影响性能,这就是用普通二维数组来表示棋盘数据的不足之处。

那么,针对以上情况,我们该如何将我们的数据格式进行优化呢?于是就引出了我们接下来的稀疏数组的概念。

1.3.稀疏数组

稀疏数组本质上也是数组,只是存储数据时只存在元数据的规模和数据两部分

稀疏数组

列是固定的3列,分别为原数组的(行,列,值)

行,第一行表示数据规模,即表示原来的数组(有多少行,有多少列,有多少个值)

如下图所示:

2.普通数组与稀疏数组互转

package com.ldp.course.structure.demo02sparsearray;

import com.ldp.course.common.MyArrayUtil;
import org.junit.Test;

import java.util.LinkedList;

/**
 * @create 06/29 7:23
 * @description <P>
 * 数据结构之稀疏数组
 * 课件:https://www.cnblogs.com/newAndHui/p/16421898.html
 * </P>
 */
public class Test01 {
    /**
     * 二维数组保存棋盘演示
     */
    @Test
    public void test01() {
        // 建立一个16*16的棋盘
        int[][] array = new int[16][16];
        // 设置2个棋子的位置
        array[8][7] = 1;
        array[9][8] = 2;
        System.out.println("显示棋盘");
        MyArrayUtil.showArray(array);
        System.out.println("二维数组转为稀疏数组");
        int[][] sparse = arrayToSparse(array);
        MyArrayUtil.showArray(sparse);
        System.out.println("稀疏数组转二维数组");
        int[][] array2 = sparseToArray(sparse);
        MyArrayUtil.showArray(array2);
    }

    /**
     * 1.确定稀疏数组的行:遍历数组得到数组的值个数n,n+1作为稀疏数组的行
     * 2.稀疏数组的列为固定值3
     * 二维数组转为稀疏数组
     *
     * @param array 二维数组
     * @return 稀疏数组
     */
    public int[][] arrayToSparse(int[][] array) {
        // 确定数组有效值个数
        int row = 0, col = 0, n = 0;
        // 记录二维数组每个值的行列值,格式(行,列,值)
        LinkedList<String> arrayStrList = new LinkedList<>();
        for (int[] ints : array) {
            row++;
            col = 0;
            for (int anInt : ints) {
                col++;
                if (anInt != 0) {
                    n++;
                    // 行,列,值
                    String str = "" + (row - 1) + "," + (col - 1) + "," + anInt;
                    arrayStrList.addLast(str);
                }
            }
        }
        // 第一行是 行,列,个数
        String strFirst = "" + row + "," + col + "," + n;
        arrayStrList.addFirst(strFirst);
        // 创建稀疏数组对象
        int[][] sparseArray = new int[n + 1][3];
        for (int i = 0; i < (n + 1); i++) {
            String s = arrayStrList.get(i);
            // System.out.println(s);
            String[] rowStr = s.split(",");
            sparseArray[i][0] = Integer.valueOf(rowStr[0]);
            sparseArray[i][1] = Integer.valueOf(rowStr[1]);
            sparseArray[i][2] = Integer.valueOf(rowStr[2]);
        }
        return sparseArray;
    }

    /**
     * 稀疏数组转二维数组
     *
     * @param sparseArray 稀疏数组
     * @return 二维数组
     */
    public int[][] sparseToArray(int[][] sparseArray) {
        int row = sparseArray[0][0];
        int col = sparseArray[0][1];
        int n = sparseArray[0][2];
        int[][] array = new int[row][col];
        // 注意这里循环i<n+1,原因是第一行是数据规模,顺然只有2个值,但是实际是3行,如下
        // [16, 16, 2]
        // [8, 7, 1]
        //[9, 8, 2]
        for (int i = 1; i < n + 1; i++) {
            int row_ = sparseArray[i][0];
            int col_ = sparseArray[i][1];
            int value_ = sparseArray[i][2];
            array[row_][col_] = value_;
        }
        return array;
    }
}

 

4.总结

在存储数组数据的时候,如果存在许多默认值的数据,可以考虑使用稀疏数组来进行存储,

这样数据相对来说就会瘦小很多,不但可以节省磁盘空间,还可以优化磁盘读写时性能。

完美

标签:sparseArray,int,稀疏,算法,详解,二维,数组,array,数据结构
来源: https://www.cnblogs.com/newAndHui/p/16421898.html