数据结构——稀疏数组(java)

1.概念分析

稀疏数组:二维数组中存在大量的无意义元素,而其中有意义的元素只占很少一部分,此时我们可以将其进行压缩,来达到减少内存消耗的作用。

2.举例

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 6 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)较多,而所含有意义的元素只有2、6;故而我们可以将其压缩。

11 11 2 
0 3 2 
5 7 6 

3.压缩规则

稀疏数组共三列,第一行存储原数组的属性,第一行第一列存储原数组行数,第一行第二列存储原数组列数,第一行第三列存储共有几个有效元素。
从第二行开始,第一列存储检索到的元素的行数,第二列存储检索到的元素的列数,第三行存储该元素的值。

4.代码实现

4.1 普通数组压缩
/**
     * 二维数组压缩
     * @author nansl
     * @param arg
     * @return
     */
    public static int[][] toSparsArray(int[][] arg){
        int sum = 0;
        for (int i = 0 ; i < arg.length ; i++){
            int[] temp = arg[i];
            for (int j = 0 ; j < temp.length ; j++){
                if (arg[i][j] != 0){
                    sum ++;
                }
            }
        }
        //时间复杂度On2
        int[][] res = new int[sum+1][3];
        res[0][0] = arg.length;
        res[0][1] = arg[0].length;
        res[0][2] = sum;
        int row = 1;
        for (int i = 0 ; i < arg.length ; i++){
            int[] temp = arg[i];
            for (int j = 0 ; j < temp.length ; j++){
                if (arg[i][j] != 0){
                    res[row][0] = i;
                    res[row][1] = j;
                    res[row][2] = arg[i][j];
                    row ++;
                }
            }
        }
        return res;
    }
4.2 数组恢复
 /**
     * 数组恢复
     * @param arg
     * @return
     */
    public static int[][] toIntegerArr(int[][] arg){
        //稀疏数组第0行第0列存储的是原数组行数
        int rowNum = arg[0][0];
        //稀疏数组第0行第1列存储的是原数组列数
        int cloNum = arg[0][1];
        int sum = arg[0][2];
        int[][] res = new int[rowNum][cloNum];
        for (int i = 1 ; i <= sum ; i++){
            int row = arg[i][0];
            int clo = arg[i][1];
            int val = arg[i][2];
            res[row][clo] = val;
        }
        return res;
    }

4.3 数组压缩后存储到本地磁盘
/**
     * 数组存储到本地磁盘中
     * @param arg
     */
    public static void sparsArrayToLocal(int[][] arg){
        File file = new File("F:\\workspaces\\file\\array.txt");
        try {
            FileWriter fileWriter = new FileWriter(file);
            for (int i = 0 ; i < arg.length ; i++){
                for (int j = 0 ; j < arg[i].length ; j++){
                    fileWriter.write(arg[i][j]+"\t");
                }
                fileWriter.write("\r\n");
            }
            fileWriter.flush();
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
4.4 本地磁盘读数组
/**
     * 本地磁盘读到数组中
     * 测试用,路径写死
     */
    public static int[][] localToSparsArray(){
        File file = new File("F:\\workspaces\\file\\array.txt");
        try {
            FileReader fileReader = new FileReader(file);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            String line;
            List<Integer> list = new ArrayList<Integer>();
            while ((line = bufferedReader.readLine()) != null){
                String[] nums = line.split("\t");
                for (int i = 0; i < nums.length; i++){
                    int num = Integer.parseInt(nums[i]);
                    list.add(num);
                }
            }
            int rows = list.size()/3;
            int[][] res = new int[rows][3];
            int clo = 0;
            for (int i = 0; i < list.size(); i++){
                res[i/3][clo] = list.get(i);
                clo++;
                if (clo == 3){
                    clo = 0;
                }
            }
            return res;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
4.5 完整代码
package com.nansl.stucts;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 稀疏数组Demo
 */
public class SparsArray {
    public static void main(String[] args) {
        int[][] a = new int[11][11];
        a[0][3] = 2;
        a[5][7] = 6;
        for (int[] b:
             a) {
            for (int c:
                 b) {
                System.out.print(c+" ");
            }
            System.out.println();
        }
        int[][] res = toSparsArray(a);
        int[][] res1 = localToSparsArray();
        for (int[] b:
                res1) {
            for (int c:
                    b) {
                System.out.print(c+" ");
            }
            System.out.println();
        }
        int[][] res2 = toIntegerArr(res);
        for (int[] b:
                res) {
            for (int c:
                    b) {
                System.out.print(c+" ");
            }
            System.out.println();
        }
    }

    /**
     * 二维数组压缩
     * @author nansl
     * @param arg
     * @return
     */
    public static int[][] toSparsArray(int[][] arg){
        int sum = 0;
        for (int i = 0 ; i < arg.length ; i++){
            int[] temp = arg[i];
            for (int j = 0 ; j < temp.length ; j++){
                if (arg[i][j] != 0){
                    sum ++;
                }
            }
        }
        //时间复杂度On2
        int[][] res = new int[sum+1][3];
        res[0][0] = arg.length;
        res[0][1] = arg[0].length;
        res[0][2] = sum;
        int row = 1;
        for (int i = 0 ; i < arg.length ; i++){
            int[] temp = arg[i];
            for (int j = 0 ; j < temp.length ; j++){
                if (arg[i][j] != 0){
                    res[row][0] = i;
                    res[row][1] = j;
                    res[row][2] = arg[i][j];
                    row ++;
                }
            }
        }
        return res;
    }

    /**
     * 数组恢复
     * @param arg
     * @return
     */
    public static int[][] toIntegerArr(int[][] arg){
        //稀疏数组第0行第0列存储的是原数组行数
        int rowNum = arg[0][0];
        //稀疏数组第0行第1列存储的是原数组列数
        int cloNum = arg[0][1];
        int sum = arg[0][2];
        int[][] res = new int[rowNum][cloNum];
        for (int i = 1 ; i <= sum ; i++){
            int row = arg[i][0];
            int clo = arg[i][1];
            int val = arg[i][2];
            res[row][clo] = val;
        }
        return res;
    }

    /**
     * 数组存储到本地磁盘中
     * @param arg
     */
    public static void sparsArrayToLocal(int[][] arg){
        File file = new File("F:\\workspaces\\file\\array.txt");
        try {
            FileWriter fileWriter = new FileWriter(file);
            for (int i = 0 ; i < arg.length ; i++){
                for (int j = 0 ; j < arg[i].length ; j++){
                    fileWriter.write(arg[i][j]+"\t");
                }
                fileWriter.write("\r\n");
            }
            fileWriter.flush();
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 本地磁盘读到数组中
     * 测试用,路径写死
     */
    public static int[][] localToSparsArray(){
        File file = new File("F:\\workspaces\\file\\array.txt");
        try {
            FileReader fileReader = new FileReader(file);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            String line;
            List<Integer> list = new ArrayList<Integer>();
            while ((line = bufferedReader.readLine()) != null){
                String[] nums = line.split("\t");
                for (int i = 0; i < nums.length; i++){
                    int num = Integer.parseInt(nums[i]);
                    list.add(num);
                }
            }
            int rows = list.size()/3;
            int[][] res = new int[rows][3];
            int clo = 0;
            for (int i = 0; i < list.size(); i++){
                res[i/3][clo] = list.get(i);
                clo++;
                if (clo == 3){
                    clo = 0;
                }
            }
            return res;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}


理解可能不到位。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值