数据结构之稀疏数组
用一个五子棋游戏的例子来理解稀疏数组
游戏进行到此时,需要存档如何用java代码实现
方式一:用一个二维数组来保存
//创建一个8X8的棋盘
int chessArr[][] = new int[8][8];
/*
* 数字0表示没有落子
* 数字1表示落白字
* 数字2表示落黑子
*/
chessArr[2][2] = 2;
chessArr[2][3] = 1;
chessArr[2][4] = 2;
chessArr[3][3] = 1;
chessArr[4][4] = 1;
//循环遍历
for (int[] is : chessArr) {
for (int i : is) {
System.out.printf("%d\t",i);
}
System.out.println();
}
打印得到的结果
此时会有很多重复的数据0,可以使用稀疏数组来做一个优化
首先我们申明一个稀疏数组sparseArr[ ][ ]
稀疏数组的第一行为固定格式,记录棋盘的大小以及非0元素的个数
sparseArr[0][0]=棋盘的行数
sparseArr[0][1]=棋盘的列数
sparseArr[0][2]=sum(棋盘中非0元素的数量,这里只有1和2两个非0元素,所以此时这个值为2)
第二行开始记录非0元素所在的行和列,以及这个非0元素的值
sparseArr[1][0]=非0元素在棋盘中的行
sparseArr[1][1]=非0元素在棋盘中的列
sparseArr[1][2]=非0元素在棋盘中的值
以此类推,代码如下
//获取二维数组中非0元素的个数
int sum = 0;
for (int i = 0; i < chessArr.length; i++) {
for (int j = 0; j < chessArr[0].length; j++) {
if (chessArr[i][j] != 0) {
sum++;
}
}
}
System.out.println("非0元素"+sum);
//申明一个稀疏数组,第一行为固定格式,所以这里取sum+1
int sparseArr[][] = new int[sum+1][3];
sparseArr[0][0] = chessArr.length;
sparseArr[0][1] = chessArr[0].length;
sparseArr[0][2] = sum;
int count = 0;
for (int i = 0; i < chessArr.length; i++) {
for (int j = 0; j < chessArr[0].length; j++) {
if (chessArr[i][j] != 0) {
//从第二行开始记录非0元素的位置
count++;
sparseArr[count][0] = i;
sparseArr[count][1] = j;
sparseArr[count][2] = chessArr[i][j];
}
}
}
System.out.println("得到稀疏数组");
for (int[] is : sparseArr) {
for (int i : is) {
System.out.printf("%d\t",i);
}
System.out.println();
}
打印结果如下:
这样相比二维数组可以节约大量存储、运算和程序运行时间。
需要读档时,将稀疏数组还原成存档时的棋盘状态,用代码实现
//还原二维数组
//申明一个二维数组来,从稀疏数组的第一行取出棋盘的行和列
int chessArr2[][] =new int[sparseArr[0][0]][sparseArr[0][1]];
//遍历稀疏数组,将稀疏数组每一行的记录的非0元素的位置和值赋值给二维数组,相当于将棋子摆回去
for (int i = 1; i < sparseArr.length; i++) {
chessArr2[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
}
//打印读档后的棋盘
for (int[] is : chessArr2) {
for (int i : is) {
System.out.printf("%d\t",i);
}
System.out.println();
}
打印结果如下:
通过这个简单的例子理解稀疏数组.