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

news2024/11/18 2:28:53

稀疏数组

      • Java 数据结构与算法
        • 数据结构
          • 简介
        • 稀疏数组(sparse array)
          • 简介
          • 二维数组转稀疏数组的思路
          • 稀疏数组转为原始的二维数组

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/692229.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多肽药物产业学习笔记

文章目录 0. 背景0.Last 1. 行业初识1.1 行业壁垒1.2 多肽药物的特性及优势1.3 小分子药的特点 多肽药物发现策略多肽药物主要治疗领域罕见病肿瘤 糖尿病(GLP-1 )胃肠道骨科免疫心血管 关于利拉鲁肽X. 几个概念X.1 CXO业务X.1.1 CDMOX.1.2 CMOX.1.3 CRO X.1.4 CMO和CDMO的联系与…

“面试造飞机,上岗拧螺丝“?2023软件测试岗面试真题超全面整理(最新版)

软件测试这个岗位&#xff0c;想要找到一份高薪的工作&#xff0c;离不开繁杂的面试程序&#xff0c;这相信是很多准备应聘软件测试岗的朋友难题&#xff0c;很多已经在职多年的软件测试工程师对于这个岗位面试都谈虎色变&#xff0c;那么&#xff0c;为什么软件测试岗位的面试…

接口测试的目的

目录 前言&#xff1a; 1、接口测试可以确保系统功能的正确性。 2、接口测试可以保证系统的可靠性。 3、接口测试有助于为客户提供最佳的用户体验。 4、接口测试还可以帮助开发人员评估系统的性能。 5、接口测试可以帮助团队提高协作效率。 前言&#xff1a; 接口测试是…

基于STM32设计的汽车修理厂环境监测系统(华为云IOT)

一、前言 生产车间的环境质量监测仅靠传统的手持式仪器仪表及手工记录无法保证数据的即时性和准确性。因此,设计并实现了一种综合传感器技术、无线通信技术和移动应用开发技术的车间环境质量监测系统。 本系统以STM32为主控芯片,外接各种传感器模块采集环境信息,并将采集数…

Windows 下后台启动 jar 包,UTF-8 启动 jar 包

目录 1. Windows 下启动 jar 包2. 设置 cmd 编码3. UTF-8 编码启动 jar 包 1. Windows 下启动 jar 包 前台启动 jar 包&#xff1a; java -jar xxx.jar后台启动 jar 包&#xff1a; javaw -jar xxx.jar后台启动 jar 包脚本&#xff08;start.bat&#xff09;&#xff1a; e…

Django框架之邮件系统,涉及HTML、富文本、附件邮件发送

参考 (892条消息) Django框架之邮件系统&#xff0c;涉及HTML、富文本、附件邮件发送_django邮件系统_李恩泽的技术博客的博客-CSDN博客https://blog.csdn.net/heroiclee/article/details/121406488 发送设置&#xff08;settings.py&#xff09; EMAIL_USE_SSL True # Sec…

通俗易懂讲解CPU、GPU、FPGA的特点

1. CPU vs GPU 大家可以简单的将CPU理解为学识渊博的教授&#xff0c;什么都精通&#xff1b;而GPU则是一堆小学生&#xff0c;只会简单的算数运算。可即使教授再神通广大&#xff0c;也不能一秒钟内计算出500次加减法。因此&#xff0c;对简单重复的计算来说&#xff0c;单单一…

畅聊职场之:作为程序员,不可不知道的银行IT岗位,收藏备选。

程序员向往的银行IT岗 1、引言2、国有商业银行2.1 中国农业银行2.2 中国邮政银行2.3 中国工商银行2.4 中国银行2.5 中国建设银行2.6 中国交通银行 3、股份制商业银行3.1 招商银行3.2 浙商银行3.3 浦发银行3.4 平安银行3.5 渤海银行3.6 中国民生银行3.7 中信银行3.8 中国光大银行…

60 KVM Skylark虚拟机混部-安装和配置

文章目录 60 KVM Skylark虚拟机混部-安装和配置60.1 安装Skylark60.1.1 硬件要求60.1.2 软件要求60.1.3 安装方法 60.2 配置Skylark60.2.1 日志60.2.2 功耗干扰控制60.2.3 LLC/MB干扰控制 60 KVM Skylark虚拟机混部-安装和配置 60.1 安装Skylark 60.1.1 硬件要求 处理器架构…

教你手把手使用 MyBatis 框架

目录 MyBatis 是什么&#xff1f; 配置 MyBatis 开发环境 方法一&#xff1a;创建项目时添加依赖 方法二&#xff1a;创建项目后添加依赖 配置连接字符串 配置 MyBatis 中的 XML 路径 业务代码 添加实体类 添加 Service 添加 Controller 增加&#xff0c;删除和修改…

Spring Boot 中的 @Configuration 注解

Spring Boot 中的 Configuration 注解 在 Spring Boot 中&#xff0c;我们经常使用注解来简化代码&#xff0c;提高效率。其中&#xff0c;Configuration 注解是一个非常重要的注解&#xff0c;它用于声明一个类作为 Spring 应用程序上下文的配置类。 在本文中&#xff0c;我…

CentOS-8 - AppStream 错误:为 repo ‘AppStream‘ 下载元数据失败

刚安装的 CentOS8 系统执行yum命令报错 CentOS-8 - AppStream 为 repo AppStream 下载元数据失败 错误&#xff1a;为 repo AppStream 下载元数据失败 原因&#xff1a;系统默认的yum源的问题…

MySQL MHA 单主架构 主从切换 高可用

MHA (Master High AvailabilityManager and tools for MySQL) 目前在MySQL高可用方面是一个相对成熟的解决方案&#xff0c;它是由日本人youshimaton采用Perl语言编写的一个脚本管理工具。目前MHA主要支持一主多从的架构&#xff0c;要搭建MHA,要求一个复制集群必须最少有3台数…

基于java+swing+mysql选课管理系统V2.0

基于javaswingmysql选课管理系统V2.0 一、系统介绍二、功能展示1.项目骨架2.项目内容3.登陆4.注册界面5、主界面6、添加选课8、修改选课 四、其它1.其他系统实现五.获取源码 一、系统介绍 项目类型&#xff1a;Java SE项目&#xff08;GUI图形界面&#xff09; 项目名称&…

深入浅出设计模式 - 桥接模式

博主介绍&#xff1a; ✌博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家✌ Java知识图谱点击链接&#xff1a;体系化学习Java&#xff08;Java面试专题&#xff09; &#x1f495;&#x1f495; 感兴趣的同学可以收…

68、基于51单片机语音识别控制小车行走系统设计(程序+原理图+PCB源文件+参考论文+开题报告+任务书+元器件清单等)

摘 要 随着电子工业的发展&#xff0c;具有语音控制功能的小车越来越受到人们的青睐&#xff0c;在人们的日常消费生活中起着不可忽视的作用。目前&#xff0c;声控技术已在很多领域得到使用。 本文对语音控制功能的小车概况做了阐述。在硬件设计方面&#xff0c;本论文以凌阳…

【Java高级语法】(二十)数学运算类:全面讲解Java数学计算的高级类库,BigDecimal、Math、Random、DecimalFormat...~

Java高级语法详解之数学运算类 1️⃣ 概念&#x1f50d; 数学运算类汇总 2️⃣ 优势和缺点3️⃣ 使用3.1 各数学计算支持类使用案例3.2 Math类解析3.3 BigDecimal类解析3.4 Random类解析3.5 DecimalFormat类解析 4️⃣ 应用场景5️⃣ 使用技巧&#x1f33e; 总结&#x1f4d1; …

ssm校园防疫管理系统-计算机毕设 附源码80315

ssm校园防疫管理系统 摘 要 2019年12月19号中国武汉发生第一例新冠病毒的到来&#xff0c;大家都在听从政府的号召在居家隔离&#xff0c;不管是在城市还是在乡镇、农村&#xff0c;这引起我的注目&#xff0c;设计一套大学ssm校园防疫管理系统&#xff0c;疫情防疫需要大家共同…

配置了git config --global credential.helper store后,还是弹出输入密码框

使用http协议拉取代码时,每次pull/push都会弹出账号密码框,可以使用git的配置credential.helper来保存每次输入的账号密码到硬盘上,命令git config --global credential.helper store,store表示存到硬盘中,但是按照这样操作后git pull还是弹出密码框,通过git config --list发现…

ESP32(MicroPython) WS2812 RGB流水灯 新版

ESP32&#xff08;MicroPython&#xff09; RGB流水灯 新版 本程序相比上一个程序&#xff0c;改用了24灯的环形WS2812模块&#xff0c;数据引脚改用13脚。增加了把相应颜色重复2次&#xff08;即前半部分和后半部分的灯颜色排列相同&#xff09;和4次的模式&#xff0c;模式增…