数据结构-非线性->稀疏数组
稀疏数组(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流知识。

浙公网安备 33010602011771号