数据结构之稀疏数组

本文详细介绍了稀疏数组的概念,为何使用及在五子棋博弈中的应用。通过Java代码演示了二维数组如何转化为稀疏数组,并提供了从稀疏数组逆向转回二维数组的方法。适合理解存储效率优化和数据结构在实际问题中的运用。
摘要由CSDN通过智能技术生成

1.什么是稀疏数组?

百度百科的定义如下:https://baike.baidu.com/item/%E7%A8%80%E7%96%8F%E7%9F%A9%E9%98%B5/3249303?fr=aladdin
稀疏数组也是二维数组,是一种较为特殊的二维数组。存储的元素是在一个非常大的二维数组中找出有效元素进行存储,但存储的元素一般较少且没有规律,所以称为稀疏数组。

2.为什么会有稀疏数组(及其应用)?

设想一个场景,在一款APP上与电脑进行五子棋博弈,而又突然有事但棋局又不想毁掉,这个时候可以选择存档保存,而针对这种棋局的存档保存一般用二维数组进行保存。再把场景拉伸一步,假设博弈时下的棋子一共就不超过10子(tip:五子棋现在国际通用格式为15x15的规格)。如图:
在这里插入图片描述
如果采用常规的二维数组进行存储,那么需要一个15x15的二维数组,能存放的元素个数是15x15个,而真正有意义的元素却只有不超过10个,而剩下的存储空间就多余以至于浪费了。
这个时候就产生了稀疏数组,只存储有效数据,而棋局的规格大小(什么时候用稀疏数组还是得根据上面稀疏数组的定义进行定夺)
上面的五子棋局对应的稀疏数组为(在程序中都是以0开始数数的):
在这里插入图片描述
解释一下这个稀疏数组,首先第一行存的是棋局的规格和棋局中有效的元素个数,因为黑白子个一个所以有效元素为2个,棋局是一个15x15规格的大小。而后稀疏数组的其他行就存储有效元素的位置以及值(ps:这里假定黑棋值为1,白棋值为2)。这样就把二维数组转为稀疏数组进行存储了,而且省了很多空间

如何用java代码进行二维数组与稀疏数组的转换呢?

在这里插入图片描述
以此图作为转换,先做以下定义,把五子棋棋谱上空的元素值定义为0,黑棋值定义为1,白棋值定义为2。

稀疏数组的列是固定的三列,行数是二维数组有效元素个数+1,因为稀疏数组第一行存的数据是二维数组的规格以及二维数组有效元素个数。所以创建稀疏数组时需要先知道二维数组的规格和有效元素。

二维数组转稀疏数组的思路:
1)遍历二维数组获取二维数组twoArr中有效元素的个数,设为count,然后创建一个二维数组用来表示稀疏数组
int[][] sparseArr = new int[count+1][3]
2)给稀疏数组的第一行赋值:
sparseArr[0][0] = twoArr.length
sparseArr[0][1] = twoArr[0].length
sparseArr[0][2] = count
3)遍历二维数组,当遍历的元素不为0时,给稀疏数组添加一行,直至遍历完整个二维数组

稀疏数组转二维数组思路:
1) 读取稀疏数组第一行,可以得知二维数组的规格从而创建一个二维数组
int row = sparseArr[0][1]
int col = sparseArr[0][2]
int[][] twoArr = new int[row][col]
2)遍历稀疏数组,把有效元素还原到二维数组
i 表示遍历的稀疏数组行数
sparseArr[i][0]表示二维数组数据的行
sparseArr[i][1]表示二维数组数据的列
sparseArr[i][2]表示二维数组数据的值
还原到二维数组:
twoArr[array[i][0]][array[i][1]] = array[i][2]

先定义一个15x15的二维数组,并把对应的黑白棋元素填上,为了二维数组更好的输出,对其进行格式化的输出,代码如下:

public static void printArray(int[][] array){
    for (int i = 0; i <array.length ; i++) {
        for (int j = 0; j <array[i].length ; j++) {
            System.out.printf("%3d",array[i][j]);
        }
        System.out.println("");
    }
}

传入一个二维数组,对其进行打印:

public static void main(String[] args) {
    int [][] arr = new int[15][15];
    arr[2][2] = 1;
    arr[3][3] = 2;
    System.out.println("-----原二维数组-----");
    printArray(arr);
}

在这里插入图片描述
创建一个方法,传入一个二维数组,最后返回一个稀疏数组:

public static int[][] twoArrToSparseArr(int[][] array){//二维转稀疏
     int count = 0;//先遍历二维数组,计算出稀疏数组的行数,稀疏数组行数=二维数组中非0数的个数+1
     for (int i = 0; i <array.length ; i++) {
         for (int j = 0; j <array[i].length ; j++) {
             if (array[i][j]!=0){
                 count = count + 1;
             }
         }
     }
     //创建一个稀疏数组
     int[][] sparseArr = new int[count+1][3];
     //创建一个稀疏数组行标,用于指示当前是稀疏数组第几行,初始化时指向第一行
     int p = 0;
     //稀疏数组的第一行初始化
     sparseArr[p][0] = array.length;//二维数组的行数
     sparseArr[p][1] = array[0].length;//二维数组的列数
     sparseArr[p][2] = count;//二维数组中非0数的个数
     //遍历二维数组转换成稀疏数组
     for (int i = 0; i <array.length ; i++) {
         for (int j = 0; j <array[i].length ; j++) {
             if (array[i][j]!=0){
                 //当二维数组的某个元素不为0,将稀疏数组行标向下移一位
                 p = p + 1;
                 //依次给稀疏数组的列赋值
                 sparseArr[p][0] = i;
                 sparseArr[p][1] = j;
                 sparseArr[p][2] = array[i][j];
             }
         }
     }
     return sparseArr;
 }

最后测试:

public static void main(String[] args) {
     int [][] arr = new int[15][15];
     arr[2][2] = 1;
     arr[3][3] = 2;
     System.out.println("-----原二维数组-----");
     printArray(arr);
     int[][] sparseArr = twoArrToSparseArr(arr);
     System.out.println("-----稀疏数组-----");
     printArray(sparseArr);
 }

在这里插入图片描述
二维数组能转为稀疏数组,自然需要稀疏数组转为二维数组:
创建一个方法,传入一个稀疏数组,最后返回一个二维数组:

public static int[][] sparseArrToTwoArr(int[][] array){
    //从稀疏数组的第一行读取二维数组的行和列
    int row = array[0][0];
    int col = array[0][1];
    int[][] twoArr = new int[row][col];
    for (int i = 1; i < array.length; i++) {//二维数组中的非0数的数据从稀疏数组的第二行开始读取
        //array[i][0]表示二维数组数据的行
        //array[i][1]表示二维数组数据的列
        //array[i][2]表示二维数组数据的值
        twoArr[array[i][0]][array[i][1]] = array[i][2];
    }
    return twoArr;
}

测试:

public static void main(String[] args) {
     int [][] arr = new int[15][15];
     arr[2][2] = 1;
     arr[3][3] = 2;
     System.out.println("-----原二维数组-----");
     printArray(arr);
     int[][] sparseArr = twoArrToSparseArr(arr);
     System.out.println("-----稀疏数组-----");
     printArray(sparseArr);
     int[][] twoArr = sparseArrToTwoArr(sparseArr);
     System.out.println("-----再转回二维数组-----");
     printArray(twoArr);
 }

在这里插入图片描述
至此稀疏数组与二维数组的转换代码就完成了,至于什么时候转换为稀疏数组以及最后保存文件等等方式,就可以根据具体需求具体分析了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值