JAVA数据结构和算法-稀释数组

374 阅读3分钟

引言:更多相关请看 JAVA数据结构和算法系列

稀疏数组

实际案例

编写的五子棋程序中,有存盘退出和续上盘的功能。

分析问题: 因为该二维数组的很多值是默认值0, 因此记录了很多没有意义的数据.->稀疏数组。

基本介绍

当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。稀疏数组的处理方法是:记录数组一共有几行几列,有多少个不同的值。把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模 如下图:

把一个6行7列的二维数据压缩为9行3列的稀疏数组

应用实例

使用稀疏数组,来保留类似前面的二维数组(棋盘、地图等等) 把稀疏数组存盘,并且可以从新恢复原来的二维数组数 整体思路分析

代码实现

/**
     * 使用稀疏数组,保留二维数组如棋盘
     * 流程:
     * 1、创建原始二维数组11*11的棋盘
     * 2、为相应坐标赋值
     * 3、获取棋盘中有值的坐标个数
     * 4、创建一个稀疏数组,n行(盘中有值的坐标个数+1)3列(行值、列值、坐标值)
     * 5、为稀疏数组赋值
     * 6、打印稀疏数组
     */
    @Test
    public void ArrToSparseArray() {
        // 1、创建原始二维数组11*11的棋盘
        System.out.println("原始二维数组11*11-------");
        int[][] arr = new int[11][11];
        // 2、为相应坐标赋值
        arr[1][2] = 1;
        arr[2][3] = 2;
        // arr[5][7] = 9; // 测试 如果放开,稀疏数组打印会加上 5 7 9
        // 3、获取棋盘中有值的坐标个数
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length; j++) {
                System.out.print(arr[i][j] + "\t");
                if (arr[i][j] != 0) {
                    sum++;
                }
            }
            System.out.println();
        }
        System.out.println("盘中有值的坐标个数:" + sum);
        // 4、创建一个稀疏数组,n行(盘中有值的坐标个数+1)3列(行值、列值、坐标值)
        int[][] sparse = new int[sum + 1][3];
        // 5、为稀疏数组赋值
        // 11(存储原始数组的行值) 11(存储原始数组的列值) 2(存储原始数组的坐标值)
        sparse[0][0] = 11;
        sparse[0][1] = 11;
        sparse[0][2] = 2;
        // 1 2 1
        // 2 3 2
        int count = 0;// 计数,给sparse赋值坐标用
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                if (arr[i][j] != 0) {
                    count++;// sparse第一行1-3列已经被占满,赋值需要从第二行开始
                    sparse[count][0] = i;// 行
                    sparse[count][1] = j;// 列
                    sparse[count][2] = arr[i][j];// 坐标值
                }
            }
        }
        // 6、打印稀疏数组
        System.out.println("打印稀疏数组:");
        for (int i = 0; i < sparse.length; i++) {
            System.out.printf("%d\t%d\t%d\t\n", sparse[i][0], sparse[i][1], sparse[i][2]);
        }
        // 11	11	2
        // 1	2	1
        // 2	3	2
    }

    /**
     * 将稀疏数组恢复为原始二维数组棋盘
     * 流程:
     * 1、先读取稀疏数组第一行的数据,得到原始二维数组大小和坐标值不为0的个数
     * 2、再读取稀疏数组后面的数据,并赋值给原始二维数组即可
     */
    @Test
    public void sparseArrayToArr() {
        // 1、创建稀疏数组
        int[][] sparse = new int[3][3];
        // 稀疏数组赋值
        // 11 11 2
        sparse[0][0] = 11;
        sparse[0][1] = 11;
        sparse[0][2] = 2;
        // 1 2 1
        sparse[1][0] = 1;
        sparse[1][1] = 2;
        sparse[1][2] = 1;
        // 2 3 2
        sparse[2][0] = 2;
        sparse[2][1] = 3;
        sparse[2][2] = 2;
        // 2、获取行列值并创建原始二维数组
        int[][] arr = new int[sparse[0][0]][sparse[0][1]];
        // 3、为原始数组赋值
        for (int i = 1; i < sparse.length; i++) {// 赋值长度从下标1开始,因为下标0已结使用了
            // arr[行:sparse[i][0]][列:sparse[i][1]] = 坐标值:sparse[i][2]
            arr[sparse[i][0]][sparse[i][1]] = sparse[i][2];
        }
        // 遍历原始数组
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                System.out.printf("%d\t", arr[i][j]);
            }
            System.out.println();
        }
    }