数据结构与算法学习--稀疏数组
一、稀疏数组
当一个数组中的大部分的元素为0 ,或者相同的数值的数组,可以使用稀疏数组来保存原来的数组。这样就可以大大减少原来的数组数据的大小。
- 稀疏数组的行数 由原来的数组的有效数据个数+1 是决定。比如二维数据 使用 稀疏数组来保存 。稀疏数组的第一行是说明 二维数组的 维数 和 有效数据个数。 其他行则说明为原二维数组的坐标值 和 有效数据值。
- 稀疏数组的列数 固定的 由原来的数组维数和原来的数组的坐标对应的值 是决定的,
比如:
二维数组 由稀疏数组 保存
稀疏数组的第一行 (8 , 6 , 10) 分别代表为 原来的二维数组 的 8 行 ,6列 和 10 个有效数据值(其他为0)
二、二维数组 转 稀疏数组的思路
- 遍历 原始的二维数组 ,得到有效数据的个数 sum
- 根据sum 就可以创建 稀疏数组 sparseArr int [ sum+1][3]
- 将根据二维数组坐标 的有效数据 逐渐存入 到 稀疏数组中
三、稀疏数组 转 二维数组 的思路
- 先读取稀疏矩阵数组的第一行 ,根据 第一行的 数据 ,创建 原始二维数组 。
- 2.在读取稀疏数组数组后几行的数据, 并赋给 原始的 二维数组 即可。
四、代码
稀疏数组与二维数组互相转换 (以文件方式保存 稀疏数组)
- 1.二维数组随机的大小随机产生,有效数据也是随机产生 , 不有效数据统一为0 。
import java.io.File;
import java.io.FileWriter;
/*
* 稀疏数组 与 二维数组 互相转换 (以文件方式保存 稀疏数组)
* 1.二维数组随机的大小随机产生,有效数据也是随机产生 , 不有效数据统一为0
*/
public class SparseArray {
public static void main(String[] args) throws Exception {
Transition transition = new Transition();
transition.sparseArrayToArray();
//transition.arrayTOSparseArray();
//System.out.println(transition.array.length);
System.out.println("array : ");
for(int i = 0 ; i < transition.arraySizeLine ; i++) {
for(int j = 0 ; j < transition.arraySizeRank ;j++) {
System.out.print(transition.array[i][j] + "\t");
}
System.out.println();
}
transition.sparseArrayToFile();
}
}
class Transition{
int arraySizeLine ; // 随机获取二维数组的 行 的大小
int arraySizeRank ;
int value ;
int arrayCoordLine[] ; // 二维数组的 行 坐标值
int arrayCoordRamk[] ; // 二维数组的 列 坐标值
int[][] array ; //产生二维数组
int[][] spaserarray;
//构造器
public Transition() {
// TODO Auto-generated constructor stub
arraySizeLine = 1 + (int)(Math.random()*10); // 随机获取二维数组的 行 的大小
arraySizeRank = 1 +(int)(Math.random()*10); // 随机获取二维数组的 列 的大小
value = 1 + (int)(Math.random()*10); //随机产生有效数据个数;
array = new int[arraySizeLine][arraySizeRank];
arrayCoordRamk = new int [value]; // 二维数组的 列 坐标值
arrayCoordLine= new int [value]; // 二维数组的 行 坐标值
spaserarray = new int[value+1][3]; //稀疏矩阵 的大小
spaserarray[0][0] =arraySizeLine;
spaserarray[0][1]=arraySizeRank;
spaserarray[0][2]=value;
System.out.println("构造器:");
System.out.println("arraySizeLine : " +arraySizeLine +"\tarraySizeRank: " + arraySizeRank + "\tvalue: " +value );
}
//随机产生的二维数组
public void arrayCreate() {
System.out.println("arrayCreate()里面的坐标值");
//可能会产生相同的坐标值 用遍历来避免相同坐标值,
//但可以坐标值大于 行列 的最大值 ,将其设计为 在0 ~arraySizeLine ,0 ~arraySizeRank 范围内。
for(int i=0 ; i< value ; ++i) {
arrayCoordLine[i] = (int)(Math.random()*arraySizeLine);
arrayCoordRamk[i] = (int)(Math.random()*arraySizeRank);
for(int j = 0 ; j < i ; j++) {
if(arrayCoordLine[i] == arrayCoordLine[j] ) { arrayCoordLine[i] = (int)(Math.random()*arraySizeLine); }
if(arrayCoordRamk[i] == arrayCoordRamk[j]) { arrayCoordRamk[i] = (int)(Math.random()*arraySizeRank) ;}
}
System.out.println("arrayCoordLine[%d]".formatted(i) + arrayCoordLine[i] + "\tarrayCoordRamk[%d] ".formatted(i) + arrayCoordRamk[i]);
}
System.out.println("输出二维数组的有效值");
for(int i=0 ; i< value ; ++i){
array[arrayCoordLine[i]][arrayCoordRamk[i]] = 1 + (int)(Math.random()*10); //随机产生有效数据大小
System.out.println(array[arrayCoordLine[i]][arrayCoordRamk[i]]);
}
}
/*
* 二维数组 转换为 稀疏数组
* 注意:sparseArray的第一行是代表 二维数组的行列数 和 有效数据个数
* 1.sparseArray [?][3] ?是有效数据个数 列数表示:原始数据的位置 和 数据大小,第一列:原始数据行;第二列:原始数据的列 ;第三个:原始数据的数据大小
* 2.有了原始数据 得到的 三种数据 ,就可以创建 稀疏数组
*/
public void arrayTOSparseArray() {
//1.(本题的特性)直接获取二维数组的有效数据(value) 大小 在构造器就可以确定了
//2.可以通过遍历 二维数组 来确定
//1.(本题的特性)直接获取二维数组的有效数据(value) 的位置数组 arrayCoordLine[i]、arrayCoordRamk[i] 在调用 arrayCreate()方法中已经可以得到
//2‘也可以通过遍历 来确定位置
arrayCreate();
System.out.println("输出稀疏数组");
System.out.println(spaserarray[0][0] + "\t"+spaserarray[0][1] + "\t"+spaserarray[0][2] );
//将 二维数组 有效数据 存在 稀疏数组中 ,从而达到压缩数据大小
for(int i =1 ; i < value+1 ; i++ ) {
for(int j=0 ; j < 3 ; j++) {
if(j==0) {spaserarray[i][j] =arrayCoordLine[i-1] ;}
else if (j==1) {spaserarray[i][j] =arrayCoordRamk[i-1] ;}
else if (j==2) {spaserarray[i][j] = array[arrayCoordLine[i-1]][arrayCoordRamk[i-1]];}
System.out.print(spaserarray[i][j] + "\t");
}
System.out.println();
}
}
public void sparseArrayToArray() {
//sparseArray的第一行是代表 二维数组的行列数 和 有效数据个数
arrayTOSparseArray();
int newarraySizeLine=spaserarray[0][0];
int newarraySizeRank=spaserarray[0][1];
int newvalue=spaserarray[0][2];
//可以知道二维数组的大小,可以创建二维数组
int[][] newArray = new int[newarraySizeLine][newarraySizeRank];
for(int i =1 ; i < newvalue+1 ; i++) {
newArray[ spaserarray[i][0] ][ spaserarray[i][1] ]= spaserarray[i][2];
}
System.out.println("新的二维数组");
for(int i = 0 ; i < newarraySizeLine ; i++) {
for(int j = 0 ; j < newarraySizeRank ;j++) {
System.out.print(newArray[i][j] + "\t");
}
System.out.println();
}
}
/*
* 将 稀疏数组 保存在文件中
*/
public void sparseArrayToFile() throws Exception {
//1.造文件
File sparseArrayFile = new File("F:\\Learning_Java\\数据结构与算法\\sparsArray.txt");
//2.造流
//2.1节点流
FileWriter fw = new FileWriter (sparseArrayFile);
//FileOutputStream fos =new FileOutputStream(sparseArrayFile);
//创建byte类型来写入文件
int length = spaserarray.length;
int rank = spaserarray[0].length;
//3.将数据写入
for(int i = 0 ; i < length ; i++) {
for(int j = 0 ; j < rank ;j++) {
fw.write(spaserarray[i][j]+"\t");
//fos.write(spaserarray[i][j]+"\t");
}
fw.write("\r\n");
}
//4.关闭流
fw.close();
}
}