前言给自己
笔者目前大三,自学java也已经有了一段时间了,现在学习进度大概在spring cloud,但是由于学习的进度较快(初入时听不懂就蜻蜓点水的学习,没有深入研究),加之java的体系庞大(主要还是后悔开始的太晚了),学到框架之后反而对以前的很多基础知识印象较浅,所以打算开始重温数据结构和算法,每天抽出部分时间来重温,之前在大二上过数据结构的课程,但是当时上课老师主要是以讲解ppt为主,主要讲解思路,基本没有实际操作,并且当时书本是使用的c、c++,而我现在自学的方向为java,这次找到一个java的数据结构课程,打算开始重温一遍数据结构和算法,因为数据结构和算法真的很重要。以前学习一直是以手写笔记为主,没有尝试过在博客上面写电子笔记,所以这也算是一次新的尝试,希望自己能够坚持自学,并能一路记录自己的学历历程。
方式
学习方式主要每天听课程后,自己再实操一遍,深入理解其底层原理,将学习过程中的不懂之处、心得、体会记录下来,学习从简入难,慢慢提升,循循渐进,不囫囵吞枣,希望在这一阶段结束后,自己的水平能有一定的提升。
稀疏数组应用场景
例如:在一个11*11的五子棋棋局中,棋盘使用二维数组进行记录,那就需要定义一个11行11列的二维数组保存。
问题分析 在数组中有很多默认值0,有很多没有意义的数据被记录下来,浪费了空间开销。
稀疏数组简介
当一个数组中的大部分的元素为0或者为同一个时,就可以用稀疏数组来进行存储。
例子:
二维数组转换稀疏思路
1、遍历原始二维数组,得到非空数据的个数cou
2、根据count
可以创建稀疏数组sparseArr int[count+1][3]
3、在稀疏数组中存储原始数组的有效数据
// 定义一个原始棋盘数组,默认值为0
int chessArr[][] = new int[11][11];
// 第二行第三列有白子
chessArr[1][2] = 1;
// 第三行第四列有黑子
chessArr[2][3] = 2;
// 输出原始数
System.out.println("原始数组");
for (int[] row : chessArr) {
for (int data : row) {
System.out.printf("%d\t", data);
}
System.out.println();
}
// 遍历原始数组,得到非空的值
int count = 0;// 计数,统计非空数值个数
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (chessArr[i][j] != 0)// 如果非空
count++;// 计数器加加
}
}
// 将原数组转换成稀疏数组
// 定义一个稀疏数组,行数为原数组非空值个数+1,列数为3
int sparseArr[][] = new int[count + 1][3];
// 头信息:
sparseArr[0][0] = 11;// 第一行第一列记录原数组行数
sparseArr[0][1] = 11;// 第一行第二列记录原数组列数
sparseArr[0][2] = count;//第一行第三列记录非空值数量
// 遍历原数组,num用于计数
for (int i = 0, num = 1; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (chessArr[i][j] != 0) {// 如果非空
// 稀疏数组存储该元素的行、列、值
sparseArr[num][0] = i;
sparseArr[num][1] = j;
sparseArr[num][2] = chessArr[i][j];
num++;
}
}
}
System.out.println("稀疏数组为:");
for (int i = 0; i < sparseArr.length; i++) {
System.out.printf("%d\t%d\t%d\t\n", sparseArr[i][0], sparseArr[i][1], sparseArr[i][2]);
}
System.out.println();
在转换换成后,可以得到输出结果:
可以看到原数组经过压缩后,变成了一个非常简单的数组,然后,我们还得考虑如何将稀疏数组转换回原来的数组。 毕竟在实际使用的时候,还是需要使用原始数组。
稀疏数组还原思路
1、定义一个二维数组,行为稀疏数组的sparseArr[0][0]
元素,列为稀疏数组的sparseArr[0][1]
元素。
2、遍历稀疏数组,将的后面每一行数据赋值给二维数组。
// 将稀疏数组还原成原数组
int row = sparseArr[0][0];// 总行数
int col = sparseArr[0][1];// 总列数
int chessArr2[][] = new int[row][col];
for (int i = 1; i < sparseArr.length; i++) {
chessArr2[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
}
System.out.println("还原的数组为:");
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
System.out.printf("%d\t", chessArr2[i][j]);
}
System.out.println();
}
文件操作
在将原始数组转化成稀疏数组后,我们应该将稀疏数组写入文件保存
public static void writerSparseArr(int[][] sparseArr) throws Exception {
// 将稀疏数组写入文件,创建一个字符缓冲输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("D:/sparseArr.txt"));
for (int[] rows : sparseArr) {
for (int data : rows) {
bw.write(data + "\t");// 写入数据,加一个制表符
}
bw.newLine();// 换行
}
bw.close(); // 释放资源,将内存缓冲去的数据刷新到文件中
System.out.println("文件写入成功");
}
可以看到,将稀疏数组写入文件。
相应的,有输入就应该有输出,我们还需要将文件中的内容读取出来赋值给稀疏数组
public static int[][] rederSparseArr() throws Exception {
// 将稀疏数组写入文件,创建字符缓冲输出流
BufferedReader br1 = new BufferedReader(new FileReader("D:/sparseArr.txt"));// 第一个用于获取文件有多少行,方便定义稀疏数组
BufferedReader br2 = new BufferedReader(new FileReader("D:/sparseArr.txt"));// 第二个用于获取数据
String line;
int count = 0;// 记录文件有多少行
int row = 0;
while ((line = br1.readLine()) != null) {
count++;// 每有一行,count++
}
int sparseArr[][] = new int[count][3];// 创建一个稀疏数组用于获取数据
while ((line = br2.readLine()) != null) {
String[] temp = line.split("\t");// 定义一个字符串数组存储
for (int i = 0; i < temp.length; i++) {
sparseArr[row][i] = Integer.parseInt(temp[i]);
}
row++;
}
System.out.println("从文件读取的稀疏数组");
for (int[] rows : sparseArr) {
for (int data : rows) {
System.out.printf("%d\t", data);
}
System.out.println();
}
br1.close();
br2.close();
return sparseArr;
}
尾声
第一次写博客,还不是很清楚该怎么写,可能会有一些错误,希望大家可以帮忙指正。也希望自己能够坚持下来。