Java数据结构与算法笔记——稀疏数组压缩算法

稀疏数组

稀疏数组就是数组中大部分的内容值都未被使用(或都为0),在数组中仅有少部分的空间使用。因此会造成内存空间的浪费。
为了节省内存空间,并且不影响数组中原有的内容值,我们可以采用一种压缩的方式来表示稀疏数组的内容。

算法效果举例

假设有一个97的数组:
在这里插入图片描述在此数组中,共有63个空间,但却只使用了5个元素,造成58个元素空间的浪费。
以下我们就使用稀疏数组重新来定义这个数组:
在这里插入图片描述第一行的三个元素表示原数组的行数、列数、使用个数
第二行开始,每行的三个元素分别代表一个元素在原数组的行数、列数、元素的值。
a[1][1]=3
a[3][0]=1

这样压缩后,原本需要63的数组,使用压缩后,只需要声明大小为6
3的数组,仅需要18个存储空间。

代码实现

package demo;

public class ArraryCompress {
    public static void main(String[] args) {
        //一般的做法,浪费内存空间,读数据的时候效率高
        long[][] arr = new long[9][7];
        arr[1][1] = 3;
        arr[3][0] = 1;
        arr[3][1] = 4;
        arr[4][2] = 7;
        arr[5][5] = 5;

        //一般这种做法在输出演示的时候,有效率一些、
        for(int i = 0;i<arr.length;i++){
            for(int j = 0;j<arr[i].length;j++){
                System.out.print(arr[i][j]+ "   ");
            }
            System.out.println();
        }

        //对稀疏数组进行压缩
        Node[] nodes = new Node[6];
        nodes[0] = new Node(9,7,5);
        nodes[1] = new Node(1,1,3);
        nodes[2] = new Node(3,0,1);
        nodes[3] = new Node(3,1,4);
        nodes[4] = new Node(4,2,7);
        nodes[5] = new Node(5,5,5);

        System.out.println("------------------对压缩后的数组进行读操作,显示出原数组----------------");

        for(int i=0;i<nodes[0].getRow();i++){
            for(int j=0; j<nodes[0].getCol();j++){
                //判断当前(i,j)坐标的位置有没有有效内容值,有就输出,没有就输出0
                int k;
                for(k=1;k<nodes.length;k++){
                    if(nodes[k].getRow()==i && nodes[k].getCol()==j){
                        break;
                    }
                }
                if(k<nodes.length){//证明这里存在有效内容值
                    System.out.print(nodes[k].getVal() + "   ");
                }else{
                    System.out.print(0 + "   ");
                }
            }
            System.out.println();
        }

        /**
         * 根据压缩内容恢复数组
         */
        System.out.println("------------------尝试恢复数组----------------");
        long[][] arr1 = new long[nodes[0].getRow()][nodes[0].getCol()];
        for(int i=1;i<nodes.length;i++){
            arr1[nodes[i].getRow()][nodes[i].getCol()] = nodes[i].getVal();
        }

        //打印数组
        for(int i = 0;i<arr1.length;i++){
            for(int j = 0;j<arr1[i].length;j++){
                System.out.print(arr1[i][j]+ "   ");
            }
            System.out.println();
        }

    }
}


class Node{
    private int row; //行数
    private int col; //列数
    private long val; //使用个数

    //用构造方法对三个属性初始化
    public Node(int row, int col, int val){
        this.row = row;
        this.col = col;
        this.val = val;
    }

    public int getRow(){
        return row;
    }

    public int getCol(){
        return col;
    }

    public long getVal(){
        return val;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值