数据结构——稀疏数组

数据结构——稀疏数组 SparseArray

稀疏数组,也可以叫做稀疏矩阵,根据[百度百科],稀疏数组是一个二维数组中有效信息较少,或者说非0元素远少于值为0的元素的数组。通常认为一个矩阵中非零元素的总数比上矩阵所有元素总数的值小于等于0.05时,则称该矩阵为稀疏矩阵(sparse matrix),该比值称为这个矩阵的稠密度。(https://baike.baidu.com/item/%E7%A8%80%E7%96%8F%E7%9F%A9%E9%98%B5/3249303?fr=aladdin)

稀疏数组存在的意义:

当一个大型二维数组中的0元素远多于非0元素时,储存或读取该数组是比较耗费机能的,因为系统要储存每一个该二维数组中的元素,即使有许多元素都为0,没有意义。那么,能不能将该矩阵进行简化,只保留少量的非0元素组成新的数组(或矩阵),这样一来只除存或是读取该简化数组,就能节约机能,提高运算效率。所以,稀疏数组出现了。

概念

比较合适的例子就是棋盘了。如下图所示,我们可以将棋盘视为一个矩阵(1111),有两个棋子分别在(1,2)和(2,3)位置。并分别用1标记黑子,2标记蓝子。这样一来,就有了由0,1,2组成的1111的矩阵,1在(1,2),2在(2,3),其他位置全部由0填满。当我们存储或读取该矩阵时还要存储或读取大量的0,没有意义,所以我们将其重新编辑成稀疏数组,只保留有用的信息。
数据结构——稀疏数组_第1张图片

如图(右侧)所示,稀疏数组的列数是固定的3列,行数为非0元素的个数+1。稀疏数组的第一行是原二维数组的特征。
(0,0):原二维数组行数;
(0,1):原二维数组列数;
(0,2):非0元素个数
(1,0):第一个非0元素在原数组位置的行数;
(1,1):第一个非0元素在原数组位置的列数;
(1,2):第一个非0元素的值;
(2,0):第二个非0元素在原数组位置的行数;
(2,1):第二个非0元素在原数组位置的列数;
(2,2):第二个非0元素的值;

由此反推,从稀疏数组变回原二维数组也并非难事,不再详谈;

java实现

上代码(此处使用3个非0元素)

public class SparseArray {
    public static void main(String[] args) {
        //1: original 2 dims atrray: 11*11
        //the locations of these 3 elements:
        int chessArray1[][] = new int[11][11];
        chessArray1[1][2] = 1;
        chessArray1[2][3] = 2;
        chessArray1[3][4] = 3;

        //output this Array
        for (int[] row : chessArray1
        ) {
            for (int data : row
            ) {
                System.out.printf("%d\t", data);//format output
            }
            System.out.println();
        }

        //retrive this 2 dims array to get the info (rows, colums and valid data)
        int sum = 0;
        //System.out.println(chessArray1.length);
        for (int i = 0; i < chessArray1.length; i++) {
            for (int j = 0; j < chessArray1.length; j++) {
                if (chessArray1[i][j] != 0) {
                    sum++;
                }
            }
        }
        //System.out.println(sum);
        //create the sparesArray:
        int sparesArray[][] = new int[sum + 1][3];//3 here is the constant value of the sparesArray
        //give the value to sparesArray
        sparesArray[0][0] = 11;
        sparesArray[0][1] = 11;
        sparesArray[0][2] = sum;//2 valid data here

        //retrive and sore the valid data into this sparesArray
        int count = 0;//counter to calculate the id of the valid data
        for (int i = 0; i < chessArray1.length; i++) {
            for (int j = 0; j < chessArray1.length; j++) {
                if (chessArray1[i][j] != 0) {
                    count++;
                    sparesArray[count][0] = i;
                    sparesArray[count][1] = j;
                    sparesArray[count][2] = chessArray1[i][j];
                }
            }
        }
              
        // System.out.println(sparesArray.length);
        //output sparaseArray:
        System.out.println();
        System.out.println("Sparse Array:");
        for (int i = 0; i < sparesArray.length; i++) {
            System.out.printf("%d\t%d\t%d\t\n", sparesArray[i][0], sparesArray[i][1], sparesArray[i][2]);
        }

        System.out.println("restore the original 2 dims array:");
        //step:
        //1. retrive the first row of the sparesArray and get the basic info of the original 2 dims array
        // (how many rows and colums and how many valid data)
        //2. retrive other rows to get the details and give that to original 2 dims array

        int chessArray2[][] = new int[sparesArray[0][0]][sparesArray[0][1]];
        for (int[]row:chessArray2
        ) {
            for (int data:row
            ) {
                System.out.printf("%d\t",data);
            }
            System.out.println();
        }

        for (int i = 1; i < sparesArray.length; i++) {
            chessArray2[sparesArray[i][0]][sparesArray[i][1]] = sparesArray[i][2];
        }
        System.out.println();
        System.out.println("original 2 dims array: ");
        for (int[]row:chessArray2
             ) {
            for (int data:row
                 ) {
                System.out.printf("%d\t",data);
            }
            System.out.println();
        }
    }
}

稀疏数组的劣势

稀疏数组是有适用范围的,通常适用于key为int类型并且有效数据量较少的情况(大约不超过1/3),可以优化内存的数据结构。但是在有效数据较多的情况下,稀疏数组效率明显低于HashMap。其次,该数据结构线程不安全,在转化过程中核能会造成数据污染。

你可能感兴趣的:(数据结构)