数据结构与算法之java语言实现(一):稀疏数组

一、概念&引入

  什么是稀疏数组?

  稀疏数组是面对一个二维数组中有众多重复元素的情况下,为了节省磁盘空间,将此二维数组转化为更加节省空间的一种数组,我们叫他稀疏数组。

  只是听概念或许会看不明白,我们来用图来演示一下:

  如图模拟为一个五子棋棋盘,其中1代表黑子,2代表白子(蓝子),我们在将其存入磁盘中,如果只是单纯的用文件io的方式将此二维数组存入磁盘,必然会造成磁盘空间的大大浪费,这时候就需要我们的稀疏数组出场了,咱们先看一下他是什么样子:

  行(row) 列(col) 值(value)
[0] 11 11 2
[1] 1 2 1
[2] 2 3 2

我们看到了一个三行两列的二维数组,首先我们看第一行,第一行的第一列(row)代表原数组有多少行,第一列的第二行(row)代表原数组有多少列,第一行第三列则代表原数组总共有多少个数据,在这个具体的例子里面,原数组是11*11,有两个值非零的值,所以第一列第三行的value值为2。

刚刚讲了第一行存储了什么东西,我们可以简单概括一下,第一行存储了原数组的整体信息,保留行,列,以及有多少个非零数值,下面我们来分析第二行。第一行存储了整体的结构,下面应当就是具体的数值,我们或许可以大致根据表格上面的文字可以猜到,第一行是存储具体的某个数据的行,第二列用于存储某个具体数值的列,第三列则用于存储具体的数值,例如:我们从上往下找发现第2行第3列为第一个非零的数值,我们这时候就可以将其存入稀疏数组中,由于Java中数组的元素存储是从零开始,所以我们第二行第三列的数据存储到具体的数组中是1,2,1,分别代表行,列,值。第三行同理,你也可以自己思考一下如何填入数据。

tips:需要强调一点:我们在填入数据的时候应当是有个count来进行计数,计数完了之后将其存入第一行的value中,我们通过value的值来维护数组的使用,如果有删除或者插入操作,我们对value的值进行修改,从而完成对数据的读取。

二、代码实现

public  static final int sparseRow = 3;public static void main(String[] args) {    int[][] oriArray = {            {0,0,0,0},            {0,1,0,0},            {0,0,1,0},            {2,0,0,0},            {0,0,0,2}

    };//静态来创建    int count = 0;
    for(int[] arr : oriArray) {        for(int i :arr) {            System.out.print(i+" ");            if(i != 0) {                count ++;            }        }        System.out.println("");    }

    System.out.println("********************");

    //init sparse     int[][] sparse = new int[count+1][sparseRow];    //init the first row     sparse[0][0] = oriArray.length;    sparse[0][1] = oriArray[0].length;    sparse[0][2] = count;    System.out.println("count:"+count);

    //通过value进行赋值,value就相当于稀疏数组的行(row)    int value = 0;    for(int m=0;m<oriArray.length;m++) {        for(int n=0;n<oriArray[m].length;n++) {            if(oriArray[m][n]!=0) {                sparse[++value][0] = m;                sparse[value][1] = n;                sparse[value][2] = oriArray[m][n];            }        }    }

    //查看稀疏数组    System.out.println("sparse: ");    for(int[] row:sparse) {        for(int col:row) {            System.out.print(col+" ");        }        System.out.println(" ");    }

    System.out.println("SUCCESSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS!");

    //上面是转换操作,下面来进行读取操作。

    int[][] arrNew =new int[sparse[0][0]][sparse[0][1]];    //从1开始,count结束,共有count个,所以一层循环即可实现    for(int j=1;j<count+1;j++) {            arrNew[j][sparse[j][1]] = sparse[j][2];    }

    //foreach来遍历输出    System.out.println("new : ");    for(int[] rowNew:arrNew) {        for(int colNew:rowNew) {            System.out.print(colNew+" ");        }        System.out.println(" ");    }?}

三、小结

稀疏数组的思路与具体实现并不难,在数据结构中很多比较难的是概念与思想,只要咱们把握住了数据结构与算法的精髓之处,写成代码具体实现也不是很难了。

原文地址:https://www.cnblogs.com/jenny2019/p/11788541.html

时间: 2024-08-29 10:21:51

数据结构与算法之java语言实现(一):稀疏数组的相关文章

《数据结构、算法与应用》8.(顺序查找数组中第一个出现指定元素的位置)

最近在读<数据结构.算法与应用>这本书,把书上的习题总结一下,用自己的方法来实现了这些题,可能在效率,编码等方面存在着很多的问题,也可能是错误的实现,如果大家在看这本书的时候有更优更好的方法来实现,还请大家多多留言交流多多指正,谢谢 8. 从左至右检查数组a[0:n-1]中的元素,以查找雨x相等的那些元素.如果找到一个元素与x相等,则函数返回x第一次出现所在的位置.如果在数组中没有找到这样的元素,函数则返回-1. // // main.cpp // Test_08 // // Created

Java语言程序设计基础篇 数组(六)

Java语法之数组 数组的定义 数组是对象. 如:int [ ]  x = new int[100];或 :int x [ ]  = new int[100];(这种方式主要是为了适应C/C++程序员) 声明一个数组变量:int [ ] x;并不会在内存中给数组分配任何空间,仅创建一个引用数组的存储地址. 数组创建后,其元素赋予默认值,数值型基本数据类型默认值为0,char类型为'\u0000',boolean类型为false. 数组的静态初始化 如:int [ ] x = new int [

数据结构与算法 基于c语言篇

学习数据结构与算法走向深蓝之路 第一章:数据结构与算法概念型 数据结构:数据之间的相互关系,即是数据的组织形式. 基本组成:{ 数据:信息的载体 数据元素:数据基本单位: } 其结构形式有四种: 1,集合结构  2,线性结构.   3,树形结构  4,图形结构 在计算机中的存储有量中形式: 顺序存储(数组形式)和非顺序存储(链式存储结构) 1.1抽象数据类型:指的是数据模型或者定义在数据模型上的一组操作 (D,R,P){ D是数据对象, R是D上的关系集 P是对D进行的操作} ListInser

排序算法(Java语言)——归并排序

归并排序mergesort中基本的操作是合并两个已排序的表.因为这两个表已排序,所以若将输出放到第三个表中,则该算法可以通过对输入数据一趟排序完成.基本的合并算法是取两个输入数组A和B,一个输出数组C,以及3个计数器Actr.Bctr.Cctr,他们初始置于对应数组的开始端.A[Actr]和B[Bctr]中的较小者被拷贝到C的下一个位置,相关的计数器向前推进一步.当两个输入表有一个用完的时候,则将另一个表中剩余部分拷贝到C中. 合并另个已排序的表的时间显然是线性的,因为最多进行N-1次比较,其中

银行家算法(Java语言实现)

package cn.hncu.mytext; import java.util.Scanner; public class BankerOfAlgorithm {//BankerOfAlgorithm 银行家算法 int Max[][]; int Allocation[][]; int Need[][]; int Available[]; int Work[]; String name[]; int temp[]; int S = 100, P = 100; int safequeue[];

《串并行数据结构与算法(SML语言)实验》题解

注意:本题解仅供参考学习,请勿直接抄袭代码,否则造成的后果和笔者无关. 第一题: 题意: 对n个数升序排序. 题解: 快排,不解释. 代码(省略了输入输出函数,下同): 1 val n = getInt (); 2 val l = getIntTable (n); 3 fun qsort [] = [] 4 | qsort l' = let 5 val p = hd l'; 6 val l1 = List.filter (fn x => x < p) l'; 7 val l2 = List.f

【数据结构与算法】java链表操作

链表操作代码量少但是比较容易出错,是比较适合面试的地方. 代码实现 /** * 源码名称:MyLinkList.java * 日期:2014-09-05 * 程序功能:java链表操作 * 版权:[email protected] * 作者:A2BGeek */ import java.util.Stack; public class MyLinkList { class LinkNode<T> { private T mValue; private LinkNode<T> mNe

数据结构与算法(java版)摘要一

1.为了得到两个完全一样的数组(1)循环遍历(2)system类的arraycopy方法. 2.当数组作为方法的参数传递时,传递的为数组的引用,对数组的操作会影响原来的数组. 3.this 关键字(1)隐式参数引用(2)调用类中的其他构造方法 4.super关键字(1)调用父类方法(2)调用父类构造方法 5.java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例.instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例.l例子

数据结构与算法(Java版)_堆

完全二叉树叫做堆. 完全二叉树就是最后一个节点之前不允许有不满的节点,就是不允许有空洞. 可以使用数组来做完全二叉树(堆). 堆分为大顶堆和小顶堆.大顶堆就是根节点上的数字是最大的,小顶堆就是根节点上的数字是最小的堆. 在堆里面的操作包括两种:插入新的节点和删除根节点. 插入新节点的操作时向上渗透.删除根节点的操作是向下渗透. 插入新节点时,把新的节点插入到最后一个位置,然后慢慢向上渗透(和父辈交换).删除根节点时,把最后一个节点放到根节点上,然后再慢慢向下渗透(和子代交换). 下面使用Java