Java | 稀疏数组

数据结构

/*
 * 数据结构包括:线性结构和非线性结构
 *  1. 线性结构:
 *      1.1 线性结构作为最常用的数据结构,其特点是数据元素之间存在一对一的线性关系
 *      1.2 线性结构有两种不同的存储结构,即顺序存储结构(数组)和链式存储结构(链表)。
 *          顺序存储的线性表称为顺序表,顺序表中的存储元素是连续的
 *          链式存储的线性表称为链表,链表中的存储元素不一定是连续的,元素节点中存放数据元素以及相邻元素的地址信息
 *      1.3 线性结构常见的有:数组、队列、链表和栈
 *  2. 非线性结构:
 *      非线性结构包括:二维数组、多维数组、广义表、树结构和图结构
*/

稀疏数组

/* 稀疏数组
 *  1. 实际需求:编写的五子棋程序(使用二维数组记录棋盘,黑子为1,白子为2,无子为0)中,有存盘退出和续上盘的功能
 *  2. 分析问题:因为二维数组存在很多值是默认值0,因此记录了很多没有意义的数据 ---> 稀疏数组
 *  3. 基本介绍:当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存数据
 *  4. 稀疏数组的处理方法:
 *      4.1. 记录数组一共有几行几列,有多少个不同的值
 *      4.2. 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
 *  5. 应用实例:
 *      5.1. 使用稀疏数组,来保留类似前面的二维数组(棋盘、地图等等)
 *      5.2. 把稀疏数组存盘,并且可以重新恢复原来的二维数组
 *
 * 二维数组转稀疏数组:
 *  1. 遍历原始的二维数组,得到有效数据的个数sum
 *  2. 根据sum就可以创建稀疏数组sparseArr int[sum + 1][3]
 *  3. 将二维数组的有效数据存入到稀疏数组
 *
 * 稀疏数组转原始的二维数组:
 *  1. 先读取稀疏数组第一行,根据第一行的数据,创建原始的二维数组
 *  2. 在读取稀疏数组后几行的数据,并赋给原始的二维数组即可
 */

二维数组与稀疏数组之间的转换

@Test
public void toSparse(){
    // 创建一个原始的二维数组 11*11
    // 0:表示没有棋子 1:黑子 2:白子
    int chessLen = 11;
    int chessArr1[][] = new int[chessLen][chessLen];
    // 当前棋盘布局
    chessArr1[1][2] = 1;
    chessArr1[2][3] = 2;
    chessArr1[4][5] = 2;
    // 输出棋盘
    for (int[] row: chessArr1){
        for (int data: row){
            System.out.printf("%d\t", data);
        }
        System.out.println();
    }
    /*
        输出:
            0	0	0	0	0	0	0	0	0	0	0
            0	0	1	0	0	0	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	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
            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
    */
    // 原始数组转稀疏数组
    // 1. 遍历原始的二维数组,得到有效数据的个数sum
    int sum = 0;
    for (int[] row: chessArr1){
        for (int data: row){
            if (data != 0){
                sum ++;
            }
        }
    }
    // 2. 根据sum就可以创建稀疏数组sparseArr int[sum + 1][3]
    int[][] sparseArr = new int[sum + 1][3];
    sparseArr[0][0] = chessLen;
    sparseArr[0][1] = chessLen;
    sparseArr[0][2] = sum;
    // 3. 将二维数组的有效数据存入到稀疏数组
    int currentRow = 0; // 当前sparseArr存入第几个数据
    for (int i = 0; i < chessLen; i++) {
        for (int j = 0; j < chessLen; j++) {
            if (chessArr1[i][j] != 0){
                currentRow ++;
                sparseArr[currentRow][0] = i;
                sparseArr[currentRow][1] = j;
                sparseArr[currentRow][2] = chessArr1[i][j];
            }
        }
    }
    // 输出稀疏数组
    for (int[] row: sparseArr){
        for (int data: row){
            System.out.printf("%d\t", data);
        }
        System.out.println();
    }
    /*
        输出:
            11	11	3
            1	2	1
            2	3	2
            4	5	2
         */
    // 稀疏数组转原始数组
    // 1. 先读取稀疏数组第一行,根据第一行的数据,创建原始的二维数组
    int arrRowLen = sparseArr[0][0];
    int arrColLen = sparseArr[0][1];
    int dataSum = sparseArr[0][2];
    int[][] chessArr2 = new int[arrRowLen][arrColLen];
    // 2. 在读取稀疏数组后几行的数据,并赋给原始的二维数组即可
    for (int i = 1; i <= dataSum; i++) {
        chessArr2[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
    }
    // 输出棋盘
    for (int[] row: chessArr2){
        for (int data: row){
            System.out.printf("%d\t", data);
        }
        System.out.println();
    }
    /*
        输出:
            0	0	0	0	0	0	0	0	0	0	0
            0	0	1	0	0	0	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	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
            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
     */
}

将稀疏数组保存到磁盘上

@Test
public void saveData(){
    // 创建一个原始的二维数组 11*11
    // 0:表示没有棋子 1:黑子 2:白子
    int chessLen = 11;
    int chessArr1[][] = new int[chessLen][chessLen];
    // 当前棋盘布局
    chessArr1[1][2] = 1;
    chessArr1[2][3] = 2;
    chessArr1[4][5] = 2;
    // 原始数组转稀疏数组
    // 1. 遍历原始的二维数组,得到有效数据的个数sum
    int sum = 0;
    for (int[] row: chessArr1){
        for (int data: row){
            if (data != 0){
                sum ++;
            }
        }
    }
    // 2. 根据sum就可以创建稀疏数组sparseArr int[sum + 1][3]
    int[][] sparseArr = new int[sum + 1][3];
    sparseArr[0][0] = chessLen;
    sparseArr[0][1] = chessLen;
    sparseArr[0][2] = sum;
    // 3. 将二维数组的有效数据存入到稀疏数组
    int currentRow = 0; // 当前sparseArr存入第几个数据
    for (int i = 0; i < chessLen; i++) {
        for (int j = 0; j < chessLen; j++) {
            if (chessArr1[i][j] != 0){
                currentRow ++;
                sparseArr[currentRow][0] = i;
                sparseArr[currentRow][1] = j;
                sparseArr[currentRow][2] = chessArr1[i][j];
            }
        }
    }
    // 将稀疏数组保存到磁盘上,比如map.dat
    FileWriter fw = null;
    BufferedWriter bw = null;
    try {
        File file = new File("SparseArr.dat");
        fw = new FileWriter(file);
        bw = new BufferedWriter(fw);
        for (int i = 0; i < sparseArr.length; i++) {
            for (int j = 0; j < sparseArr[i].length; j++) {
                bw.write(sparseArr[i][j] + "\t");
            }
            bw.write("\n");
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

恢复原来的数组,读取sparseArr.dat进行恢复

@Test
public void parseData(){
    // 将稀疏数组保存到磁盘上,比如map.dat
    FileReader fr = null;
    BufferedReader br = null;
    try {
        File file = new File("SparseArr.dat");
        fr = new FileReader(file);
        br = new BufferedReader(fr);
        String str = br.readLine();
        String[] s = str.split("\t");
        // 1. 先读取稀疏数组第一行,根据第一行的数据,创建原始的二维数组
        int arrRowLen = Integer.parseInt(s[0]);
        int arrColLen = Integer.parseInt(s[1]);
        int dataSum = Integer.parseInt(s[2]);
        int[][] chessArr = new int[arrRowLen][arrColLen];
        str = br.readLine();
        while (str != null){
            s = str.split("\t");
            // 2. 在读取稀疏数组后几行的数据,并赋给原始的二维数组即可
            chessArr[Integer.parseInt(s[0])][Integer.parseInt(s[1])] = Integer.parseInt(s[2]);
            str = br.readLine();
        }
        // 输出棋盘
        for (int[] row: chessArr){
            for (int data: row){
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
发布了36 篇原创文章 · 获赞 3 · 访问量 6208

猜你喜欢

转载自blog.csdn.net/Oh_MyBug/article/details/104909474
今日推荐