Java实现数据结构稀疏数组

稀疏数组

基本介绍:当一个数组中大部分元素为0,或者是同一个值的数组时,可以使用稀疏数组来保存该数组

应用场景

如下我们用来表示一个棋盘,1,2表示在该位置的落子分别是白色和黑色,那么可以看到,此时棋盘上的大部分位置是还没落子的,如果我们进行存盘操作,就需要将该二维数组全部保存起来,显然很耗费资源,那么我们就可以将这个二维数组转换为稀疏数组来进行保存

0 0 0 0 0 0 0 0 0 0 0
0 0 2 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 2 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0

转换为稀疏数组后是这样的

11 11 4
6 3 1
5 6 2
2 0 2
1 2 2

稀疏数组sparseArray中,第一行第一列表示了原始数组的行数,第一行第二列表示了原始数组的列数,第一行第三列表示了原始数组的有效值个数。从第二行开始,第一列表示有效值在原始数组中的行标,第二列表示有效值在原始数组中的列标,第三列表示有效值。所以可以总结出来,稀疏数组的初始化大小公式为

//sum为原始数组中的有效值个数
int[][] spareArray=new int[sum+1][3]

代码实现

原始数组转稀疏数组

1.确定原始数组的有效值个数

2.初始化稀疏数组

3.再一次遍历原始数组拿到有效值得位置

稀疏数组转原始数组

1.通过第一行的第一列,第二列可以初始化好原始数组

2.在从第二行开始遍历,第一列就是有效值在原始数组中的行标,第二列就是有效值在原始数组中的列表,第三列就是有效值

/**
     * 将原始数组转换为稀疏数组
     * @param array 原始数组
     * @return 转换后的稀疏数组
     */
public static int[][] conversionToSparseArray(int[][] array){
    int effective=0;
    //得到原始二维数组的有效个数,从而确定稀疏数组的行数
    for(int[] row:array){
        for (int data:row){
            if(data!=0){
                effective++;
            }
        }
    }

    int[][] sparseArray=new int[effective+1][3];

    //稀疏数组的的第一行存储原始数组的相关信息
    sparseArray[0][0]= array.length;
    sparseArray[0][1]=array[0].length;
    sparseArray[0][2]=effective;

    for(int i=0;i< array.length;i++){
        for(int j=0;j<array[0].length;j++){
            if(array[i][j]!=0){
                //注意理解使用有效个数来暂定放入的行,实际上从稀疏数组的从下往上赋值,即第一个有效数字放在了稀疏数组的最后一行,依次类推
                sparseArray[effective][0]=i;
                sparseArray[effective][1]=j;
                sparseArray[effective][2]=array[i][j];
                effective--;
            }
        }
    }
    return sparseArray;
}

/**
     * 转换稀疏数组为原始数组
     * @param sparseArray 稀疏数组
     * @return 原始数组
     */
public static int[][] conversionToArray(int[][] sparseArray){
    //从稀疏数组的第一行中获取到原始数组的信息
    int rowSum=sparseArray[0][0];
    int colSum=sparseArray[0][1];
    int[][] array=new int[rowSum][colSum];
    //第二行开始遍历稀疏数组中的值放入到原始数组中
    for(int i=1;i< sparseArray.length;i++){
        int row=sparseArray[i][0];
        int col=sparseArray[i][1];
        int number=sparseArray[i][2];
        array[row][col]=number;
    }
    return array;
}

完整代码实现

public class SparseArrayTest {
    private static final Random RANDOM=new Random(2);

    /**
     * 数组打印工具方法
     * @param array 需要打印的数组
     */
    public static void print(int[][]array){

        for(int[] row:array){
            for (int data:row){
                System.out.printf("%d\t",data);
            }
            System.out.println();
        }
    }

    /**
     * 创建随机赋值的二维数组
     * @param row 行数
     * @param col 列数
     * @param effective 数组有效值个数
     * @return 初始化完成的二维数组
     */
    public static int[][] randomArray(int row,int col,int effective){
        int[][] array=new int[row][col];
        for(int i=0;i<effective;i++){
            int randomRow= RANDOM.nextInt(row);
            int randomCol=RANDOM.nextInt(col);
            int randomNumber=RANDOM.nextInt(3);
            array[randomRow][randomCol]=randomNumber;
        }
        return array;
    }

    /**
     * 将原始数组转换为稀疏数组
     * @param array 原始数组
     * @return 转换后的稀疏数组
     */
    public static int[][] conversionToSparseArray(int[][] array){
        int effective=0;
        //得到原始二维数组的有效个数,从而确定稀疏数组的行数
        for(int[] row:array){
            for (int data:row){
                if(data!=0){
                    effective++;
                }
            }
        }

        int[][] sparseArray=new int[effective+1][3];

        sparseArray[0][0]= array.length;
        sparseArray[0][1]=array[0].length;
        sparseArray[0][2]=effective;

        for(int i=0;i< array.length;i++){
            for(int j=0;j<array[0].length;j++){
                if(array[i][j]!=0){
                    //注意理解使用有效个数来暂定放入的行,实际上从稀疏数组的从下往上赋值
                    sparseArray[effective][0]=i;
                    sparseArray[effective][1]=j;
                    sparseArray[effective][2]=array[i][j];
                    effective--;
                }
            }
        }
        return sparseArray;
    }

    /**
     * 保存稀疏数组到磁盘中
     * @param array 需要保存的稀疏数组
     * @param path 文件路径
     */
    public static void saveSparseArray(int[][] array,String path){
        File file=new File(path);
        //使用对象流将稀疏数组写入磁盘
        try(ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream(file))){
            objectOutputStream.writeObject(array);
            objectOutputStream.flush();
        }
        catch(IOException e){
            e.printStackTrace();
        }
    }

    /**
     * 解析磁盘中的数据为原始稀疏数组
     * @param path 文件路径
     * @return 解析后的稀疏数组
     */
    public static int[][] parseSparseArray(String path){
        File file=new File(path);
        try(ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream(file))
           ){
            Object data=objectInputStream.readObject();
            if(data instanceof int[][]){
                return (int[][])data;
            }
        }catch(IOException |ClassNotFoundException e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 转换稀疏数组为原始数组
     * @param sparseArray 稀疏数组
     * @return 原始数组
     */
    public static int[][] conversionToArray(int[][] sparseArray){
        int rowSum=sparseArray[0][0];
        int colSum=sparseArray[0][1];
        int[][] array=new int[rowSum][colSum];
        for(int i=1;i< sparseArray.length;i++){
            int row=sparseArray[i][0];
            int col=sparseArray[i][1];
            int number=sparseArray[i][2];
            array[row][col]=number;
        }
        return array;
    }

    public static void main(String[] args) {
        int[][] array=ArrayUtil.randomArray(11,11,5);
        System.out.println("-------------原始数组-----------");
        print(array);

        System.out.println("-------------稀疏数组-----------");
        int[][] sparseArray=conversionToSparseArray(array);
        print(sparseArray);

        //保存路径,根据自身需求决定
        String path="D:\\桌面\\笔记\\数据结构和算法\\Practice\\Practice\\DataStructures\\src\\main\\resources\\sparseArray.txt";
        saveSparseArray(sparseArray,path);

        int[][] parseSparseArray=parseSparseArray(path);

        System.out.println("-------------文件解析到的稀疏数组-----------");
        print(parseSparseArray);

        System.out.println("-------------文件解析到的稀疏数组转换为原始数组-----------");
        int[][] parseArray=conversionToArray(parseSparseArray);
        print(parseArray);
    }

}
测试结果
-------------原始数组-----------
0	0	0	0	0	0	0	0	0	0	0	
0	0	2	0	0	0	0	0	0	0	0	
2	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	2	0	0	0	0	
0	0	0	1	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
-------------稀疏数组-----------
11	11	4	
6	3	1	
5	6	2	
2	0	2	
1	2	2	
-------------文件解析到的稀疏数组-----------
11	11	4	
6	3	1	
5	6	2	
2	0	2	
1	2	2	
-------------文件解析到的稀疏数组转换为原始数组-----------
0	0	0	0	0	0	0	0	0	0	0	
0	0	2	0	0	0	0	0	0	0	0	
2	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	2	0	0	0	0	
0	0	0	1	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
0	0	0	0	0	0	0	0	0	0	0	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值