Java数据结构预算法之稀疏数组

alicelmx 2019-12-01

Java稀疏数组

定义

稀疏数组:数组中的大部分元素值都没有使用(或者都为0),在数组中仅有少部分的空间使用,造成了内存空间的浪费。

使用新的压缩的方式表示原来数组的方式为稀疏数组。

为什么要使用稀疏数组?

为了节省内存空间。

稀疏数组实现原理

引入应用场景

开发人员需要开发一个五子棋的游戏,为了实现存档、悔棋和判断棋局胜负,需要对这些棋子的位置进行存储,由于棋盘是一个矩形的,所以可以使用二维数组。

但是想象下棋过程,我们可能会给许多没有使用的位置分配内存(即数组中大部分数据是0或者为同一个值),所以在这里引入稀疏数组。

稀疏数组的实现

必须强调一点,稀疏数组是由二维数组变换而成的。

稀疏数组的列数是固定的,一共有3列,分别是行、列、对应的值(对应二维数组上的值)。

稀疏数组的首行是记录对应的二维数组是几行几列以及有效值的数量。

接下来的每一行都是记录有效值在对应二维数组中的行列以及值。

接下来我们用一个例子来表示,比如这里有一个二维数组:,按照上面的方法可以转化成稀疏数组。
Java数据结构预算法之稀疏数组

稀疏数组Java实现

那么稀疏数组和二维数组应该如何转换呢?

二维数组变换成稀疏数组

  • 遍历原始的二维数组,得到有效数据个数sum
  • 根据sum创建稀疏数组 int[sum+1][3]
  • 将二位数组的有效数据存入稀疏数组(第一行为二维数组的行列和有效值的个数)
public static int[][] twoToSparse(int[][] two){
        int sum = 0;
        // 第一步 计算非零值的个数
        int row = two.length;
        int col = two[0].length;
        for (int i=0;i<row;i++){
            for (int j=0;j<col;j++){
                if(two[i][j]!=0){
                    sum++;
                }
            }
        }
        //创建稀疏数组
        int sparseArr[][] = new int[sum+1][3];
        //给稀疏数组赋值
        sparseArr[0][0] = 11;
        sparseArr[0][1] = 11;
        sparseArr[0][2] = sum;

        // 遍历二维数组,把非零的数据填充进去
        int count = 0;
        for (int i=0;i<row;i++){
            for (int j=0;j<col;j++){
                if(two[i][j]!=0){
                    count++;
                    sparseArr[count][0] = i;
                    sparseArr[count][1] = j;
                    sparseArr[count][2] = two[i][j];
                }
            }
        }
        return sparseArr;
    }

稀疏数组转换成二维数组

  • 根据稀疏第一行,创建原始二位数组
  • 读取后面的数据并且赋值给原始的二维数组即可
public static int[][] sparseToTwo(int[][] sparse){
        // 将稀疏数组恢复成二维数组
        int rows = sparse[0][0];
        int cols = sparse[0][1];
        int myCount = sparse[0][2];
        int[][] reArr = new int[rows][cols];
        for(int i=1;i<sparse.length;i++){
            int arrrow = sparse[i][0];
            int arrcol = sparse[i][1];
            int arrNum = sparse[i][2];
            reArr[arrrow][arrcol] = arrNum;
        }
        return reArr;
    }

完整代码

package com.folm.dataStructure.SparseArray;

import java.io.*;
import java.util.Arrays;

public class SparseArray {

    public static int[][] twoToSparse(int[][] two){
        int sum = 0;
        // 第一步 计算非零值的个数
        int row = two.length;
        int col = two[0].length;
        for (int i=0;i<row;i++){
            for (int j=0;j<col;j++){
                if(two[i][j]!=0){
                    sum++;
                }
            }
        }
        //创建稀疏数组
        int sparseArr[][] = new int[sum+1][3];
        //给稀疏数组赋值
        sparseArr[0][0] = 11;
        sparseArr[0][1] = 11;
        sparseArr[0][2] = sum;

        // 遍历二维数组,把非零的数据填充进去
        int count = 0;
        for (int i=0;i<row;i++){
            for (int j=0;j<col;j++){
                if(two[i][j]!=0){
                    count++;
                    sparseArr[count][0] = i;
                    sparseArr[count][1] = j;
                    sparseArr[count][2] = two[i][j];
                }
            }
        }
        return sparseArr;
    }

    public static int[][] sparseToTwo(int[][] sparse){
        // 将稀疏数组恢复成二维数组
        int rows = sparse[0][0];
        int cols = sparse[0][1];
        int myCount = sparse[0][2];
        int[][] reArr = new int[rows][cols];
        for(int i=1;i<sparse.length;i++){
            int arrrow = sparse[i][0];
            int arrcol = sparse[i][1];
            int arrNum = sparse[i][2];
            reArr[arrrow][arrcol] = arrNum;
        }
        return reArr;
    }

    public static void main(String[] args){
        // 创建一个原始的二维数组 11 * 11
        // 0:表示没有棋子  1 表示黑色 0 表示蓝色
        int chessArr1[][] = new int[11][11];
        chessArr1[1][2] = 1;
        chessArr1[2][3] = 2;
        chessArr1[4][5] = 2;
        // 输出原始的二维数组
        System.out.println("原始的二维数组");
        for(int[] row:chessArr1){
            for(int data:row){
                System.out.printf("%d\t",data);
            }
            System.out.println();
        }
        int sparseArr[][] = twoToSparse(chessArr1);
        // 输出稀疏数组的形式
        System.out.println();
        System.out.println("得到的稀疏数组的形式:");
        for(int i=0;i<sparseArr.length;i++){
            System.out.printf("%d\t%d\t%d\t\n",sparseArr[i][0],sparseArr[i][1],sparseArr[i][2]);
        }
        int[][] newTwo = sparseToTwo(sparseArr);
        System.out.println("之后的二维数组:");
        for(int[] row:newTwo){
            for(int data:row){
                System.out.printf("%d\t",data);
            }
            System.out.println();
        }
    }
}

Good luck!

相关推荐