数据结构-非线性->稀疏数组

稀疏数组(sparse array)

定义:如果一个数组(包括多维数组)中的大部分元素为0(或者为同一个值的数组时),为了节约空间,可以使用稀疏数组来保存该数组。

功能

(1)记录原始数组总共有几行几列,以及有多少个有效值(下图中右边稀疏数组第0行)。

(2)通过一个小规模的数组记录原始数组中有效值的行,列和该值(下图中右边稀疏数组第0行之后),从而缩小原始数组的规模。

                                                  稀疏数组实例:

 

 

 

 
 
 
 
 
 
 
 
 
应用场景
    需求:简单模拟一个五子棋盘,并将稀疏数组存盘以及恢复原来的二维数组

    思路分析:

      原始二维数组 ---> 稀疏数组:

   1.遍历原始二维数组,得到数组中有效值 sum;

   2.根据sum创建稀疏数组sparse array;

   3.将二维数组中的有效值存到稀疏数组。

   稀疏数组 --> 恢复二维数组:

   1.读取稀疏数组第一行,根据稀第一行数组创建二维数组;

   2.读取稀疏数组第一行之后的数据,并赋给二维数组。

Java代码实现

  1 package Work.DataStructure;
  2 
  3 import java.io.*;
  4 
  5 /**
  6  * 稀疏数组案例:棋盘案例
  7  */
  8 public class SparseArray {
  9     private int[][] arr1;
 10     private int[][] arr2;
 11     private int[][] sparseArr;
 12     private static int sum;
 13     public static void main(String[] args) {
 14         SparseArray sa = new SparseArray();
 15         sa.arr1();
 16         sa.sparseArr();
 17         sa.arr2();
 18         try {
 19             sa.sparseArrFromIo(sum);
 20         }catch(Exception e){e.printStackTrace();}
 21     }
 22     /**
 23      * 创建初始二维数组arr1
 24      */
 25     public void arr1(){
 26         arr1 = new int[11][11];
 27         arr1[0][0] = 1;
 28         arr1[2][3] = 2;
 29         arr1[3][5] = 1;
 30         arr1[10][10] = 2;
 31         for(int i = 0; i<arr1.length;i++){
 32             for(int j =0;j<arr1[i].length;j++){
 33                 if(arr1[i][j] != 0){
 34                     sum++;
 35                 }
 36             }
 37         }
 38         System.out.println("========这里是原始二维数组========");
 39         for(int[] row : arr1){
 40             for(int data : row){
 41                 System.out.printf("%d\t",data);
 42             }
 43             System.out.println();
 44         }
 45         System.out.println("sum: "+sum);
 46     }
 47 
 48     /**
 49      * 二维数组 --> 稀疏数组
 50      */
 51     public void sparseArr(){
 52         int count =0 ;
 53         //根据二维数组中的有效值创建稀疏数组
 54         sparseArr = new int[sum+1][3];
 55         sparseArr[0][0] = 11;
 56         sparseArr[0][1] = 11;
 57         sparseArr[0][2] = sum;
 58         //将原始二维数组的有效值添存入稀疏数组中
 59         System.out.println("=======这里是稀疏数组========");
 60         for(int i = 0;i<arr1.length;i++){
 61             for(int j =0;j<arr1[i].length;j++){
 62                 if( arr1[i][j] != 0) {
 63                     count++;
 64                     sparseArr[count][0] = i;
 65                     sparseArr[count][1] = j;
 66                     sparseArr[count][2] = arr1[i][j];
 67                 }
 68             }
 69         }
 70         for(int i = 0; i<sparseArr.length;i++){
 71             System.out.printf("%d\t%d\t%d\t\n",sparseArr[i][0],sparseArr[i][1],sparseArr[i][2]);
 72         }
 73         try{
 74             sparseArrToIo(sparseArr);
 75         }
 76         catch(Exception e){e.printStackTrace();}
 77     }
 78 
 79     /**
 80      * 稀疏数组  --> 二维数组
 81      */
 82     public void arr2(){
 83         //根据稀疏数组的第一行数据创建二维数组
 84         arr2 = new int[sparseArr[0][0]][sparseArr[0][1]];
 85         //根据稀疏数组第一行之后的数据将二维数组有效值还原
 86         for(int i =1 ;i <sparseArr.length;i++){
 87             arr2[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
 88         }
 89         System.out.println("========这里是还原后的二维数组========");
 90         for( int[] row :arr2){
 91             for(int data: row){
 92                 System.out.printf("%d\t",data);
 93             }
 94             System.out.println();
 95         }
 96     }
 97 
 98     /**
 99      *将稀疏数组存入磁盘
100      */
101     public void sparseArrToIo(int[][] sparseArr) throws Exception{
102         File file = new File("D:\\4-Code\\sparseArr.txt");
103         if(! file.exists()){
104             file.createNewFile();
105         }
106         FileOutputStream fos = new FileOutputStream(file);
107         StringBuilder sb = new StringBuilder();
108         for(int i = 0; i < sparseArr.length;i++){
109             sb.append(sparseArr[i][0]+" "+sparseArr[i][1]+" "+sparseArr[i][2]+"\n");
110         }
111         fos.write(sb.toString().getBytes());
112         fos.flush();
113         fos.close();
114     }
115     /**
116      * 读取磁盘中的稀疏数组
117      */
118     public static void sparseArrFromIo(int row) throws Exception{
119         System.out.println("========这里是从磁盘中读取的稀疏数组========");
120         int[][] sarr = new int[row+1][3];
121         FileReader fr = new FileReader("D:\\4-Code\\sparseArr.txt");
122         BufferedReader br = new BufferedReader(fr);
123         String temp = "";
124         String[] tarr = null;
125         int count =0;
126         while((temp = br.readLine())!=null){
127             tarr = temp.split(" ");
128             sarr[count][0] = Integer.valueOf(tarr[0]);
129             sarr[count][1] = Integer.valueOf(tarr[1]);
130             sarr[count][2] = Integer.valueOf(tarr[2]);
131             count++;
132         }
133         for(int i =0;i<sarr.length;i++){
134             System.out.printf("%d\t%d\t%d\t\n",sarr[i][0],sarr[i][1],sarr[i][2]);
135         }
136     }
137 }

运行结果:

 1 ========这里是原始二维数组========
 2 1    0    0    0    0    0    0    0    0    0    0    
 3 0    0    0    0    0    0    0    0    0    0    0    
 4 0    0    0    2    0    0    0    0    0    0    0    
 5 0    0    0    0    0    1    0    0    0    0    0    
 6 0    0    0    0    0    0    0    0    0    0    0    
 7 0    0    0    0    0    0    0    0    0    0    0    
 8 0    0    0    0    0    0    0    0    0    0    0    
 9 0    0    0    0    0    0    0    0    0    0    0    
10 0    0    0    0    0    0    0    0    0    0    0    
11 0    0    0    0    0    0    0    0    0    0    0    
12 0    0    0    0    0    0    0    0    0    0    2    
13 sum: 4
14 =======这里是稀疏数组========
15 11    11    4    
16 0   0     1    
17 2   3     2    
18 3   5     1    
19 10    10    2    
20 ========这里是还原后的二维数组========
21 1    0    0    0    0    0    0    0    0    0    0    
22 0    0    0    0    0    0    0    0    0    0    0    
23 0    0    0    2    0    0    0    0    0    0    0    
24 0    0    0    0    0    1    0    0    0    0    0    
25 0    0    0    0    0    0    0    0    0    0    0    
26 0    0    0    0    0    0    0    0    0    0    0    
27 0    0    0    0    0    0    0    0    0    0    0    
28 0    0    0    0    0    0    0    0    0    0    0    
29 0    0    0    0    0    0    0    0    0    0    0    
30 0    0    0    0    0    0    0    0    0    0    0    
31 0    0    0    0    0    0    0    0    0    0    2    
32 ========这里是从磁盘中读取的稀疏数组========
33 11    11    4    
34 0     0     1    
35 2     3     2    
36 3     5     1    
37 10    10    2    

小结:

   通过该实例可得知,稀疏数组直观的功能实现思路主要是通过一个小规模的(固定列)二维数组储存另一个含有很多无效数据的规模大(重复数据)的数组,对于数组的操作更多的是通过循环来实现两个数组之间的转换,类似压缩文件和解压文件的过程;对于数据存入磁盘和从磁盘中读取数据则是用到基本的IO流知识。

 

posted @ 2020-08-31 10:30  sixsixman  阅读(250)  评论(0)    收藏  举报