大家好,我是瑞的居,今天分享的是稀疏数组的学习。本人也仅仅是想记录跟着b站狂神up学习的过程。
一、稀疏数组的举例与概述
稀疏数组举例
需求:编写五子棋游戏中,有存盘退出和还原上一盘的功能。
(先记住这个需求,这是敲代码所需的思路之一 —— 用新建的数组接收原始数组变成稀疏数组、再建一个新数组接收还原的稀疏数组变回原始数组)
分析:棋盘如图所示,如果我们把棋盘看成二维数组,那就是有很多的地方还没有下棋子。
![](https://img-blog.csdnimg.cn/img_convert/09465dde143e502da9d68e1b5de05996.png)
因此,
我们来使用二维数组(11行11列)记录上述的棋盘,无棋是0、黑棋是1、白棋是2,则如下图所示:
![](https://img-blog.csdnimg.cn/img_convert/335128a564eb049f8435f3be7d257a47.png)
稀疏数组概述
当数组中大部分元素为0或者为同一值的元素时,可以使用稀疏数组来保存该数组;
用稀疏数组,当然也是因为它能压缩空间啦!最初的时候空间是很值钱滴。
稀疏数组的处理方法:
记录数组一共几行几列,有多少个不同的值;
把具有不同值的元素和行、列及值压缩记录在一个小规模的数组中。
二、原始数组与稀疏数组的转换
如下图所示,我们来理解它们的转换关系:
稀疏数组中第0行的6、7、8表示:原始数组中有6行、7列、8个非零的数值;
这些都是头部信息而已。
稀疏数组的第1行才才才才才开始记录原始数组中每一行每一列的具体信息;
如:第1行表示:原始数组的第0行、第3列的数值为22;
如:第2行表示:原始数组的第0行、第6列的数值为15;
如:第3行表示:原始数组的第1行、第1列的数值为11;
以此类推,不再赘述……
![](https://img-blog.csdnimg.cn/img_convert/734b8c37f1d87a465467dbb90d31a791.png)
三、编写代码
练习第一步:创建一个二维数组代替棋盘
//1.创建一个二维数组代替棋盘 11*11 0:没有棋子; 1:黑棋子; 2:白棋子
int[][] array1 = new int[11][11];
array1[1][2] = 1;
array1[2][3] = 2;
//输出原始的数组,这是foreach方法;下面我都用不同的遍历方法练习一下,但它们意思一样
System.out.println("输出原始的数组:");
for (int[] array11 : array1) {
for (int a : array11) {
System.out.print(a+"\t");
}
System.out.println();
}
输出结果如下:
![](https://img-blog.csdnimg.cn/img_convert/fa43136214b7b9a8295ebc93cc49e8e8.png)
练习第二步:把原始的数组转换为稀疏数组来保存
//2.转换为稀疏数组来保存
//算出原始数组里面有效的值(非0的值)并取出;
int sum = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (array1[i][j] != 0){
sum++;
}
}
}
System.out.println("有效值的个数:"+sum );
//创建一个代表稀疏数组的数组
int[][] array2 = new int[sum+1][3];
array2[0][0] = 11;
array2[0][1] = 11;
array2[0][2] = sum;
//通过以上的几步,就把稀疏数组的头部打出来了
//遍历二维数组,将非零的值,存放到稀疏数组中
int count = 0;//它代表第几行
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
if (array1[i][j]!=0){
//为什么先count++?因为从第二行开始,第一行(黄色的[0])它是稀疏数组的头部啊!!
//为什么知道是[0]、[1]、[2],因为稀疏数组不就三列吗?只会是行数不一样!!
count++;
array2[count][0] = i;
array2[count][1] = j;
array2[count][2] = array1[i][j];
}
}
}
//输出稀疏数组,咱们知道就3列,不必按嵌套循环的套路输出
System.out.println("稀疏数组");
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i][0]+"\t"
+array2[i][1]+"\t"
+array2[i][2]+"\t");
}
练习第三步:尝试把稀疏数组还原为原始数组
//1.建个新数组读取稀疏数组,把新数组还原为原始数组
//如上述练习第二步所示:array2[0][0] = 11、array2[0][1] = 11,我们本来也清楚知道
int[][] array3 = new int [array2[0][0]][array2[0][1]];
//2.把原始数组的元素还原变回它的值,也就是把一些非0的值还原回来;
//下面的第一个循环:i 为什么从 1 开始,因为第0行是稀疏数组的头部信息!!
//首先,再次想明白,稀疏数组的具体数据是从第1行开始,第0行还不是!!
//其次,它也只有3列啊!第0列、第1列、第2列!!
//最后,它第1列,不就是原始数组第3列的横坐标吗?
// 它第2列,不就是原始数组第3列的纵坐标吗?
//这不就是array3[array2[i][0]][array2[i][1]] = array2[i][2];的意思吗?
for (int i = 1; i < array2.length; i++) {
array3[array2[i][0]][array2[i][1]] = array2[i][2];
}
//3.把还原后的数组打印出来看看
for (int i = 0; i < array3.length; i++) {
for (int j = 0; j < array3[i].length; j++) {
System.out.print(array3[i][j]+"\t");
}
System.out.println();
}
输出结果如下图所示:
![](https://img-blog.csdnimg.cn/img_convert/ac3c8dc720631c676cb27cfd82677042.png)
四、总结
总体有一点点点绕,本人水平有限,欢迎各位批评指正,一起进步;
特别是array3[array2[i][0]][array2[i][1]] = array2[i][2];
上面的array3[ ][ ],只不过这两个括号里面分别是array2[i][0]、array2[i][1];但它们的值不就是两个数字吗,对不对?
不知道有没有人看,评论区求推荐一些好用的截图工具~