数据结构、算法学习笔记开篇——稀疏数组

1 篇文章 0 订阅
1 篇文章 0 订阅

前言给自己

笔者目前大三,自学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;
	}

在这里插入图片描述

尾声

第一次写博客,还不是很清楚该怎么写,可能会有一些错误,希望大家可以帮忙指正。也希望自己能够坚持下来。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值