_橘猫学数据结构与算法
在学习和了解稀疏数组之前,让我们先通过一个实际的案例来打通关口。
五子棋这款小游戏,我想各位看官并不陌生,其实在编写五子棋程序时棋盘使用的就是我们最熟悉不过的的二维数组来实现的。其游戏规则就是同色号的棋子由五个连续不间断的排成一排就可以获胜。当然,我的主要目的不是来向大家来介绍这款小游戏的,而是来探究一下这款游戏所使用的数据结构与算法。
在玩五子棋的时候,我们肯定都会注意到,在游戏的上方会有两个小功能:存盘退出和续上盘的功能。那么,这两个功能到底是如何实现的呢?接下来,让我们一步步巡查真像。
在这里,我就简单的模拟了一下五子棋的棋盘,并使用二维数组进行展列出来,但是看图的时候,大家有没有发现一个问题,在数组中,数字1和2 分别对应到了棋盘中的黑棋和蓝棋,由于数组中没有赋值的位置,数组会生成一个默认值0,因此,就会记录了很多没有意义的数据,那这种情况是如何解决的呢?这个时候,稀疏数组就会对此发挥自己强大的作用。
那么问题来了,稀疏数组又是什么呢?有的同学一眼就可以发现,稀疏数组不也是个数组吗,的确,但是此数组非彼数组,在五子棋这个小游戏当中可是发挥着不可或缺的作用的。那到底什么是稀疏数组呢?它又有什么特点呢?下面就让我们着重介绍一下稀疏数组。
稀疏数组:
概述:当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方法:
(1). 记录一个数组一共有几行几列,有多少个不同的值.
(2). 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
稀疏数组的应用实例:
(1). 使用稀疏数组,来保留类似前面的二维数组(棋盘、地图等等)
(2). 把稀疏数组存盘,并且可以从新恢复原来的二维数组
下面介绍一下二维数组与稀疏数组之间相互转换的思路:
(二维数组:chessArr[ ][ ] 、稀疏数组:sparseArr [ ][ ])
(1)二维数组 转 稀疏数组思路
1.遍历 原始的二维数组,得到非零数据(或有效数据)个数 sum
2.根据 sum就可以创建稀疏数组sparseArr int [sum+1] [3]
3.将二维数组的有效数据存入到 稀疏数组
(1)稀疏数组 转 二维数组思路
1.先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组,比如上面的chessArr[7] [7]
2.在读取稀疏数组后几行的数据,并赋给原始的二维数组 即可
最后用代码实现:
//二维数组 转 稀疏数组
//创建一个原始的二维数组 7 * 7
//0:表示没有棋子 1表示 黑子 2 表示 蓝子
int chessArr1[][] = new int[7][7];
chessArr1[1][2] = 1;
chessArr1[2][3] = 2;
//输出原始的二维数组
System.out.println("原始的二维数组");
for (int[] row : chessArr1){//从每一行中获取元素内容
for (int data: row){//从遍历的每行中,在逐个遍历一列的元素
System.out.printf("%d\t",data); //这样就可以获得二维表的每一个元素的内容
}
System.out.println();
}
//将二维数组 转 稀疏数组 思路
//1.先遍历二维数组,得到非0 的数据的个数
int sum =0;
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 7; j++) {
if (chessArr1[i][j] != 0){
sum++;
}
}
}
//2.创建稀疏数组
int sparseArr[][] = new int[sum+1][3];
//给稀疏数组赋值
sparseArr[0][0] = 7;
sparseArr[0][1] = 7;
sparseArr[0][2] = sum;
//遍历二维数组,将非0 的值存放到sparseArr中
int count = 0;//count 用于记录是第几个非0数据
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 7; j++) {
if (chessArr1[i][j]!=0){
count++;
sparseArr[count][0] = i;
sparseArr[count][1] = j;
sparseArr[count][2] = chessArr1[i][j];
}
}
}
//输出稀疏数组的形式
System.out.println();
System.out.println("得到的稀疏数组为如下形式");
for (int i = 0; i < sparseArr.length; i++) {
System.out.printf("%d\t%d\t%d\t",sparseArr[i][0],sparseArr[i][1],sparseArr[i][2]);
System.out.println();
}
System.out.println();
理解完上面的二维数组 转 稀疏数组,下面让我们再恢复成原二维数组
//将稀疏数组 ---> 恢复成 原始的二维数组
/*
* 1. 先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组,比如上面的chessArr2 = int[7][7]
* 2. 在读取稀疏数组后几行的数据,并赋给 原始的二维数组 即可.
* */
//先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组
int chessArr2[][] = new int[sparseArr[0][0]][sparseArr[0][1]];
//2.在读取稀疏数组后几行的数据(从稀疏数组的第二行开始遍历,因为第一行存储的是原数组的行和列),并赋给 原始的二维数组 即可
for (int i = 1; i < sparseArr.length; i++) {
chessArr2[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
}
//输出恢复后的二维数组
System.out.println();
System.out.println("输出恢复后的二维数组");
for (int[] ints : chessArr2) {
for (int anInt : ints) {
System.out.printf("%d\t",anInt);
}
System.out.println();
}
恭喜恭喜,学会了哦!!!