回顾总结之数据结构:1 稀疏数组

稀疏数组能将一个二维数组进行压缩,节省存储空间。稀疏数组的列数固定为 3,对于原始数组中的某个有效元素,会对应稀疏数组中的一行,依次记录其在原始数组中的行、列、值三个信息。其本质还是一个二维数组,因此也是非线性结构。
相关源码:https://gitee.com/flying-morning/data-structure/tree/master/src/com/datastructure/sparse

1 应用场景

当一个数组中大部分元素为0或者同一个值,可以使用稀疏数组,核心就两点:

  1. 记录一个数组的行、列数,不同的值个数
  2. 把具有不同值的元素的行、列以及值的信息记录在一个小规模数组中

下面这个图就是网上流传比较广的一个普通数组转稀疏数组的图,这里借用下。
在这里插入图片描述

2 稀疏数组和普通数组的转换

普通二维数组转为稀疏数组:

  1. 遍历原始数据,得到不同元素(有效元素)的个数 count;
  2. 创建稀疏数组, sparsearray[count+1][3],行数是有效元素个数加1;
  3. 将普通数组中的有效数据记录到稀疏数组。稀疏数组,第一行分别记录原始数组的总行数、总列数、有效值个数;后面每一行则记录一个数据元素,依次对应在原始数组中的行号、列号、值
    //将二维原始数组转换为稀疏数组
    public int[][] convertToSparseArr (int[][] originArray) {
    
    
        int rowLen= originArray.length;
        int colLen = originArray[0].length;
        //有效元素个数
        int numOfValidElement = countValidElement(originArray);

        int[][] sparerArray = new int[numOfValidElement+1][3];
        //稀疏数组的第一行
        sparerArray[0][0] = rowLen;
        sparerArray[0][1] = colLen;
        sparerArray[0][2] = numOfValidElement;
        //生成稀疏数组的元素
        int count = 0; //第几(count)个有效元素
        for (int i=0;i<rowLen;++i) {
    
    
            for (int j=0;j<colLen;++j) {
    
    
                if (originArray[i][j] !=0) {
    
    
                    ++count;
                    sparerArray[count][0] = i;
                    sparerArray[count][1] = j;
                    sparerArray[count][2] = originArray[i][j];
                }
            }
        }
        return  sparerArray;
    }

稀疏数组转为原始数组:

  1. 读取稀疏数组第一行,获取原始数组的行数、列数,并创建原始数组;
  2. 读取稀疏数据后续每一行数据,根据行、列、值信息,填充原始数组。
    //将稀疏数组转换为原始二维数组
    public int[][] convertToOriginArr(int[][] sparseArray) {
    
    
        //获取原始数组行列信息
        int rowLen = sparseArray[0][0];
        int colLen = sparseArray[0][1];
        int[][] originArray = new int[rowLen][colLen];
        for(int i=1;i<sparseArray.length;++i) {
    
    
            int[] line = sparseArray[i];
            originArray[line[0]][line[1]] = line[2];
        }
        return originArray;
    }

3 结果验证以及完整源码

3.1 结果验证

生成的原始数组,3 个有效元素:
在这里插入图片描述
转换成稀疏数组:
在这里插入图片描述
再通过稀疏数组转换成原始数组:
在这里插入图片描述

3.2 完整源码

更多数据结构相关源码,欢迎访问码云获取,https://gitee.com/flying-morning/data-structure/tree/master/src/com/datastructure/sparse

import java.util.Random;

public class SparseArray {
    
    
    public static void main(String[] args) {
    
    
        SparseArray mSparseArr = new SparseArray();

        //创建原始二维数组
        int[][] originArr = mSparseArr.generateOriginArr();
        mSparseArr.printArr(originArr,"原始数组");

        //生成稀疏数组
        int[][] sparseArr = mSparseArr.convertToSparseArr(originArr);
        mSparseArr.printArr(sparseArr,"稀疏数组");

        //将稀疏数组转换成普通二维数组
        int [][] originArrFromSparse = mSparseArr.convertToOriginArr(sparseArr);
        mSparseArr.printArr(originArrFromSparse,"从稀疏数组还原后的数组");
    }

    /**
     * 生成原始二维数组 10*10
     * 随机选择三个位置,产生非 0 有效数字
     */
    public int[][] generateOriginArr() {
    
    
        int[][] originArr = new int[10][10];
        //to generate 3 non-zero number
        Random random = new Random();
        for(int i=0;i<3;++i) {
    
    
            int row = random.nextInt(9);
            int col = random.nextInt(9);
            originArr[row][col] = 1;
        }
        return  originArr;
    }

    //打印数组
    public void printArr(int[][] array,String type) {
    
    
        System.out.println(type + ":");
        for(int[] row:array) {
    
    
            for(int num:row) {
    
    
                System.out.print(num + "\t");
            }
            System.out.println();
        }
    }

    //将二维原始数组转换为稀疏数组
    public int[][] convertToSparseArr (int[][] originArray) {
    
    
        int rowLen= originArray.length;
        int colLen = originArray[0].length;
        //有效元素个数
        int numOfValidElement = countValidElement(originArray);

        int[][] sparerArray = new int[numOfValidElement+1][3];
        //稀疏数组的第一行
        sparerArray[0][0] = rowLen;
        sparerArray[0][1] = colLen;
        sparerArray[0][2] = numOfValidElement;
        //生成稀疏数组的元素
        int count = 0; //第几(count)个有效元素
        for (int i=0;i<rowLen;++i) {
    
    
            for (int j=0;j<colLen;++j) {
    
    
                if (originArray[i][j] !=0) {
    
    
                    ++count;
                    sparerArray[count][0] = i;
                    sparerArray[count][1] = j;
                    sparerArray[count][2] = originArray[i][j];
                }
            }
        }
        return  sparerArray;
    }

    //统计原始数组中有效元素(非0)的个数,尽管我们知道是 3
    private int countValidElement(int[][] originArray) {
    
    
        int count = 0;
        for(int[] row:originArray) {
    
    
            for (int num : row) {
    
    
                if (num != 0) {
    
    
                    ++count;
                };
            }
        }
        System.out.println("有效元素个数为: " + count);
        return count;
    }

    //将稀疏数组转换为原始二维数组
    public int[][] convertToOriginArr(int[][] sparseArray) {
    
    
        //获取原始数组行列信息
        int rowLen = sparseArray[0][0];
        int colLen = sparseArray[0][1];
        int[][] originArray = new int[rowLen][colLen];
        for(int i=1;i<sparseArray.length;++i) {
    
    
            int[] line = sparseArray[i];
            originArray[line[0]][line[1]] = line[2];
        }
        return originArray;
    }
}

猜你喜欢

转载自blog.csdn.net/hejnhong/article/details/125354767