稀疏数组-Java数据结构和算法

很基础的知识, 但是越基础越应该重视


前言

      当我们进行下五子棋的时候你有没有想过, 棋盘是怎么生成的? 下棋的过程是怎么实现的? 还有我们在退出游戏的时候, 可以选择保存, 数据又是怎么保存的呢? 又怎么恢复棋盘呢?
      显然对于一个棋盘来说, 我们可以用一个二维数组来存储数据(0代表没有棋子, 1代表白方棋子, 2代表黑方棋子), 来进行棋盘的存储和恢复; 但是显然我们的棋盘中会存在大量的0(可以理解为无效数据) , 那么我们有没有方法来优化存储结构呢?显然是有的:


一、稀疏数组是什么?

      如果矩阵中的有效数据非常少(就是含有大量的重复数据), 我们可以用一个另一个数组只存储有效的数据的信息(坐标 和 值)即可, 这样的数组 可以和原来的数组相互转换, 称之为 稀疏数组

      当一个数组元素大部分是0的时候(大部分数据相同的时候即可), 可以使用稀疏数组来保存该数组;
      稀疏数组的处理方法:
      (1)记录数组一共有几行几列
      (2)把具有不同值的元素的行列值记录在一个小规模的数组中, 从而缩小程序的规模
      (3)在这里为了方便理解我用Excel做了一张图, 如下(坐标从0开始):

在这里插入图片描述


二、转换思路(二维数组↔稀疏数组)

      根据上面画的图可以得知: 我们的稀疏数组需要提取出来第一行来保存棋盘行列总数 以及有效数据个数sum 因此我们的系数数组 行数为sum + 1 列数为 3 即可, 具体步骤如下:

ps: 关于为什么 将棋盘的 行列数 保存在稀疏数组 第一行中:
      我们虽然可以将其定义为全局变量, 但是当我们将数在不同设备上加载本局游戏的时候 我们还是会丢失 棋盘总大小的信息, 所我们需要将其保存下来.

				 二维数组 转 稀疏数组:
1. 遍历原始的数组, 得到有效数据的个数(这里用sum来表示)
2. 根据sum的值我们就可以创建稀疏数组:
	int[] sparseArray = new int[sum + 1][3]
3. 将二维数组有效数据的信息 (行 列 值) 存放到 稀疏数组
4. 最后将稀疏数组保存到磁盘即可
				
				稀疏数组 转 二维数组(恢复)
5. 先读取 稀疏数组的第一行, 根据第一行的数据 创建 原始的二维数组 ,比如上图中的第一行数据:
	chessArr = int[8][8]
6. 再读取稀疏数组后几行的数据, 并赋值给原始的二维数组chessArr即可

代码如下(按照上图的棋子数据):

package 稀疏数组;

import javax.sound.midi.Soundbank;

/**
 * @author Weilei Zhang
 */
public class SparseArray {
    public static void main(String[] args) {
        //创建一个原始的二维数组
        //0:表示没有棋子, 1:表示白色的棋子, 2.表示黑色的棋子
        int chessArr1[][] = new int[8][8];
        chessArr1[2][5] = 2;//棋子的位置
        chessArr1[4][4] = 2;
        chessArr1[5][3] = 1;
        //输出原始的数组:
        System.out.println("原始的二维数组:");
        for(int[] row : chessArr1){
            for(int i : row){
                System.out.printf("%d\t" , i);
            }
            System.out.println();
        }

        int sum = 0;

        for(int i = 0 ;  i < 8 ; i++){
            for(int j = 0 ; j < 8 ; j++){
                if(chessArr1[i][j] != 0){
                    sum++;
                }
            }
        }
//        2.创建对应的稀疏数组
        int sparseArr[][] = new int[sum + 1][3];
//        给稀疏数组赋值
        sparseArr[0][0] = 8;
        sparseArr[0][1] = 8;
        sparseArr[0][2] = sum;
        int hang = 1;
        for(int i = 0 ; i < 8 ; i++){
            for(int j = 0 ; j < 8 ; j++){
                if(chessArr1[i][j] != 0){
                    sparseArr[hang][0] = i;
                    sparseArr[hang][1] = j;
                    sparseArr[hang][2] = chessArr1[i][j];
                    hang++;
                }
            }
        }
        System.out.println("稀疏数组为:");
        for(int[] a : sparseArr){
            for(int i : a){
                System.out.printf("%d\t" , i);
            }
            System.out.println();
        }

//        将稀疏数组复原:
    /*
        1.先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组.比如上面的chessArr2[8][8]
        2.再读取稀疏数组的后几行数据,并赋值给原始的二维数组
     */

        int chessArr2[][] = new int[sparseArr[0][0]][sparseArr[0][1]];

//        便利稀疏数组,给恢复的数组赋值
        for(int i = 1 ; i < sparseArr.length ; i++){
            chessArr2[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
        }
//        输出恢复好的数组
        System.out.println("恢复好的数组为:");
        for (int[] i : chessArr2) {
            for(int j : i){
                System.out.printf("%d\t" , j);
            }
            System.out.println();
        }
    }
}


总结

      很简单的转换, 也是很实用的方法, 需要注意的就是稀疏数组第一行要存储的数据, 注意下标的范围即可, 对于保存在磁盘上的操作就没有写在这里.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值