数据结构之稀疏数组

我将在实现二维稀疏数组的基础上,梳理下稀疏数组的概念及应用。

1、概念

  其实还是数组,通过规定,将数组元素赋予特定含义,将数据量较少,但占用空间较大的数组,用较小的存储空间保存起来的数组。

  规定:

    稀疏数组第一行,第一列,保存了原数组的行数

    稀疏数组第一行,第二列,保存了原数组的列数

    稀疏数组第一行,第三列,保存了原数组的元素个数

2、应用举例

  这里还是借用网上用的比较多的棋盘保存来举例实现。

  在一个10*10的五子棋棋盘上,用户下了黑色,白色的棋子数枚。

  (1)现需要将当前棋盘进行存盘;

  (2)可以进行读盘操作恢复当前棋盘。

  代码实现如下:

  (1)定义一个二维数组来模拟棋盘

// 定义一个二维数组,数组值为1表示黑子,2表示白子
        int[][] chessAr = new int[10][10];
        chessAr[2][2] = 1;
        chessAr[5][6] = 1;
        chessAr[2][3] = 2;
        chessAr[3][3] = 1;
        chessAr[7][2] = 2;
        chessAr[8][6] = 1;
        for(int[] a : chessAr){
            System.out.println(Arrays.toString(a));
        }

// 打印效果如下
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 2, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 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, 0]
[0, 0, 2, 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, 0]

  (2)定义稀疏数组,模拟存盘情况

        // 计算二维数组元素个数
        int size = 0;
        for (int i = 0;i<chessAr.length;i++){
            for(int j=0;j<chessAr[i].length;j++){
                if (chessAr[i][j] == 1 || chessAr[i][j] == 2){
                    size++;
                }
            }
        }


        // 定义一个稀疏数组
        int[][] sparseArray = new int[size+1][3];

        sparseArray[0][0] = 10;
        sparseArray[0][1] = 10;
        sparseArray[0][2] = size;

        for(int[] a : sparseArray){
            System.out.println(Arrays.toString(a));
        }

        // 稀疏数组记录二维数据信息
        int flag = 1;
        for (int i = 0; i < chessAr.length; i++) {
            for (int j = 0; j < chessAr[i].length; j++) {
                if (chessAr[i][j] == 1 || chessAr[i][j] == 2) {
                    sparseArray[flag][0] = i;
                    sparseArray[flag][1] = j;
                    sparseArray[flag][2] = chessAr[i][j];
                    flag++;
                }
            }
        }
        System.out.println();
        System.out.println();
        System.out.println();
        for(int[] a : sparseArray){
            System.out.println(Arrays.toString(a));
        }

// 稀疏数组打印如下
[10, 10, 6]
[2, 2, 1]
[2, 3, 2]
[3, 3, 1]
[5, 6, 1]
[7, 2, 2]
[8, 6, 1]

(3)通过稀疏数组恢复棋盘

// 定义一个空二维数组
        int[][] chessArr2 = new int[sparseArray[0][0]][sparseArray[0][1]];
        // 二维数据根据稀疏数组记录填充
        for(int i = 1 ;i < sparseArray.length ; i++){
            chessArr2[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
        }
        System.out.println();
        System.out.println();
        System.out.println();
        for(int[] a : chessArr2){
            System.out.println(Arrays.toString(a));
        }

// 打印效果如下
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 2, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 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, 0]
[0, 0, 2, 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, 0]

3、稀疏数据使用注意

  实际开发过程中,一定牢记,我们使用稀疏数据是为了更好的节省系统空间,从而提高性能。

  所以在使用前,需要对容器的数据量进行预估判断,防止滥用。

  如,10*10的二维数组,若正常保存占用100个元素的空间,与数组元素值是否有意义无关。

  当其中有33个元素有意义时,使用稀疏数组保存,则占用空间为33*3+3 = 102,此时,使用稀疏素组反而不合适。

  

 

posted on 2020-08-18 13:43  温柔的青竹十六夜  阅读(217)  评论(0)    收藏  举报