数据结构与算法之稀疏数组

文章介绍了稀疏数组的概念,它是当二维数组大部分元素为同一值时进行压缩得到的。通过举例说明了在五子棋棋盘存储中如何利用稀疏数组减少无意义数据。文章详细阐述了二维数组转稀疏数组和稀疏数组转回二维数组的思路及代码实现,展示了数据结构优化的效果。
摘要由CSDN通过智能技术生成

Java 数据结构与算法

该学习代码都在🔗

数据结构
简介

数据结构包括:线性结构和非线性结构

线性结构

  1. 线性结构作为最常用的数据结构,其特点是数据元素之间存在一对一的线性关系。
  2. 线性结构有两种不同的存储结构,即顺序存储结构和链式存储结构。顺序存储的线性表称为顺序表,顺序表中存储的元素是连续的(地址)。
  3. 链式存储的线性表称为链表。链表中的存储元素不一定是连续的(地址),元素节点中存放数据元素以及相邻元素的地址信息。
  4. 线性结构常见的有:数组,队列,链表和栈。

非线性结构

非线性结构包括:二维数组,多维数组,广义表,数结构,图结构等。

稀疏数组(sparse array)
简介

稀疏数组是对 当一个数组中大部分元素为同一个值的时候,对原数组进行压缩得到的数组,压缩过后的数组为稀疏数组。

示例

在一个五子棋程序中,有存盘退出,和续上盘的功能。
在这里插入图片描述

使用二维数组记录棋盘。(1-黑子, 2-白子)

在这里插入图片描述

问题:

因为该二维数组的很多值都是默认值0, 因此记录了很多没有意义的数据。

处理方法:

  1. 记录数组一共有几行几列,有多少个不同的值。
  2. 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模。

如:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EUkZx0d1-1687871866230)(java数据结构与算法.assets/image-20230619221951492.png)]

转换后的稀疏数组,第一行记录原数据的行树,列数,值的数量。而后每一行记录的都是每一个值的位置以及值。

二维数组转稀疏数组的思路
  1. 遍历 原始的二维数组,得到有效数据的个数 sum.
  2. 根据sum 就可以创建 稀疏数组 sparser[sum+1][3].
  3. 将二维数组的有效数据存入到稀疏数组。

稀疏数组转原始的二维数组的思路

  1. 先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组。
  2. 遍历稀疏数组,根据稀疏数组的值,赋值给原始的二维数组

代码实现

  1. 先定义原始二维数组与格式化数组方法
 public static void main(String[] args) {
        // 初始化原始二维数组
        int[][] chessArr = init();
        toStringArr(chessArr);
    }


    /**
     * 初始原始的二维数组,11 * 11
     * 描述:0-没有棋子,1-黑子,2-白子
     * @return
     */
    public static int[][] init(){
        int[][] chessArr = new int[11][11];
        // 第二行第三列为黑子,第三行第四列为白子
        chessArr[1][2] = 1;
        chessArr[2][3] = 2;
        return chessArr;
    }

    /**
     * 输出二维数组
     * @param arr
     */
    public static void toStringArr(int[][] arr){
        for (int[] row : arr) {
            for (int data : row) {
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }
    }

打印如下:

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	2	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
  1. 定义稀疏数组基础方法
public static void main(String[] args) {
        // 初始化原始二维数组
        int[][] chessArr = init();
        toStringArr(chessArr);
        System.out.println("--------");
        // 原始二维数组转为稀疏数组
        int[][] sparseArr = chessArrConvertSparseArr(chessArr);
        toStringArr(sparseArr);

    }

/**
     * 原始二维数组转为稀疏数组
     * @param chessArr
     * @return
     */
    public static int[][] chessArrConvertSparseArr(int[][] chessArr){
        // 1. 先进行初始化稀疏数组
        int[][] sparseArr = initSparseArr(chessArr);
        // 2. 赋值稀疏数组
        int index = 1; // 定义下标,用于对稀疏数组赋值使用
        for (int i = 0; i < chessArr.length; i++) {
            for (int j = 0; j < chessArr[i].length; j++) {
                if (chessArr[i][j] != 0){
                    sparseArr[index][0] = i; // 记录行下标
                    sparseArr[index][1] = j; // 记录列下标
                    sparseArr[index][2] = chessArr[i][j]; // 记录值
                    index++;
                }
            }
        }
        return sparseArr;
    }
/**
     * 初始化稀疏数组
     * 注意:稀疏数组固定为3列
     * @param chessArr 原始的二维数组
     * @return
     */
    public static int[][] initSparseArr(int[][] chessArr){
        // 获取行数和列数
        int row = chessArr.length;
        int col = chessArr[0].length;
        // 获取原始数组的有效值的数量
        int validSum = getArrayValidSum(chessArr);
        int[][] sparseArr = new int[validSum + 1][3];
        sparseArr[0][0] = row;
        sparseArr[0][1] = col;
        sparseArr[0][2] = validSum;
        return sparseArr;
    }

    /**
     * 获取二维数组的有效的个数
     * @param arr
     * @return
     */
    public static int getArrayValidSum(int[][] arr){
        int sum = 0;
        for (int[] row : arr) {
            for (int data : row) {
                if (data != 0){
                    sum++;
                }
            }
        }
        return sum;
    }

稀疏数组打印如下:

11 11	2	
1	 2	1	
2	 3	2

结论:由原始的二维数组 11 * 11 转为 稀疏数组后为 3 * 3。其压缩所节约资源可观。

稀疏数组转为原始的二维数组

代码如下:

public static void main(String[] args) {
        // 初始化原始二维数组
        int[][] chessArr = init();
        toStringArr(chessArr);
        System.out.println("--------");
        // 原始二维数组转为稀疏数组
        int[][] sparseArr = chessArrConvertSparseArr(chessArr);
        toStringArr(sparseArr);
        System.out.println("==========");
        // 稀疏数组转为原始的二维数组
        int[][] chessArr1 = sparseArrConvertChessArr(sparseArr);
        toStringArr(chessArr1);
    }

/**
     * 将稀疏数组转为原始的二维数组
     * 1. 先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组。
     * 2. 遍历稀疏数组,根据稀疏数组的值,赋值给原始的二维数组
     * @param sparseArr
     * @return
     */
    public static int[][] sparseArrConvertChessArr(int[][] sparseArr){
        int row = sparseArr[0][0];     // 获取原始的二维数组的行数
        int col = sparseArr[0][1];     // 获取原始的二维数组的列数
        // 初始化原始的二维数组
        int[][] chessArr = new int[row][col];
        // 遍历稀疏数组,赋值给原始的二维数组, 过滤其第一条数据,因为第一条存储的是整个原始二维数据的结构
        for (int i = 1; i < sparseArr.length; i++) {
            chessArr[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
        }
        return chessArr;
    }

打印如下:

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	2	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值