1.背景
1.1.假設讓你開發一個五子棋,你會如何存儲棋盤
1.2.數組保存棋盤
假設:
0-白表示空白位置(即沒有走過的位置)
1-表示白棋
2-表示黑棋
如果是數組保存棋盤,你會發現很多數據都是零,如下圖:
上面,我們通過二維數組的方法,將棋盤數據保存在了一個二維數組中,整個數組我們用了 16 × 16(共 256)個點來保存數據,其中有 254 個點都是空的。
實際來說,我們只需要將有價值的黑白子保存起來即可,因爲只要我們知道黑白子數據,以及棋盤的大小,那麼這 254 個空點是可以不用進行保存的。
把這樣沒有價值的數據起來,不但會浪費存儲空間的大小,如果寫入到磁盤中,還會增大 IO 的讀寫量,影響性能,這就是用普通二維數組來表示棋盤數據的不足之處。
那麼,針對以上情況,我們該如何將我們的數據格式進行優化呢?於是就引出了我們接下來的稀疏數組的概念。
1.3.稀疏數組
稀疏數組本質上也是數組,只是存儲數據時只存在元數據的規模和數據兩部分
稀疏數組
列是固定的3列,分別爲原數組的(行,列,值)
行,第一行表示數據規模,即表示原來的數組(有多少行,有多少列,有多少個值)
如下圖所示:
2.普通數組與稀疏數組互轉
package com.ldp.course.structure.demo02sparsearray; import com.ldp.course.common.MyArrayUtil; import org.junit.Test; import java.util.LinkedList; /** * @create 06/29 7:23 * @description <P> * 數據結構之稀疏數組 * 課件:https://www.cnblogs.com/newAndHui/p/16421898.html * </P> */ public class Test01 { /** * 二維數組保存棋盤演示 */ @Test public void test01() { // 建立一個16*16的棋盤 int[][] array = new int[16][16]; // 設置2個棋子的位置 array[8][7] = 1; array[9][8] = 2; System.out.println("顯示棋盤"); MyArrayUtil.showArray(array); System.out.println("二維數組轉爲稀疏數組"); int[][] sparse = arrayToSparse(array); MyArrayUtil.showArray(sparse); System.out.println("稀疏數組轉二維數組"); int[][] array2 = sparseToArray(sparse); MyArrayUtil.showArray(array2); } /** * 1.確定稀疏數組的行:遍歷數組得到數組的值個數n,n+1作爲稀疏數組的行 * 2.稀疏數組的列爲固定值3 * 二維數組轉爲稀疏數組 * * @param array 二維數組 * @return 稀疏數組 */ public int[][] arrayToSparse(int[][] array) { // 確定數組有效值個數 int row = 0, col = 0, n = 0; // 記錄二維數組每個值的行列值,格式(行,列,值) LinkedList<String> arrayStrList = new LinkedList<>(); for (int[] ints : array) { row++; col = 0; for (int anInt : ints) { col++; if (anInt != 0) { n++; // 行,列,值 String str = "" + (row - 1) + "," + (col - 1) + "," + anInt; arrayStrList.addLast(str); } } } // 第一行是 行,列,個數 String strFirst = "" + row + "," + col + "," + n; arrayStrList.addFirst(strFirst); // 創建稀疏數組對象 int[][] sparseArray = new int[n + 1][3]; for (int i = 0; i < (n + 1); i++) { String s = arrayStrList.get(i); // System.out.println(s); String[] rowStr = s.split(","); sparseArray[i][0] = Integer.valueOf(rowStr[0]); sparseArray[i][1] = Integer.valueOf(rowStr[1]); sparseArray[i][2] = Integer.valueOf(rowStr[2]); } return sparseArray; } /** * 稀疏數組轉二維數組 * * @param sparseArray 稀疏數組 * @return 二維數組 */ public int[][] sparseToArray(int[][] sparseArray) { int row = sparseArray[0][0]; int col = sparseArray[0][1]; int n = sparseArray[0][2]; int[][] array = new int[row][col]; // 注意這裏循環i<n+1,原因是第一行是數據規模,順然只有2個值,但是實際是3行,如下 // [16, 16, 2] // [8, 7, 1] //[9, 8, 2] for (int i = 1; i < n + 1; i++) { int row_ = sparseArray[i][0]; int col_ = sparseArray[i][1]; int value_ = sparseArray[i][2]; array[row_][col_] = value_; } return array; } }
4.總結
在存儲數組數據的時候,如果存在許多默認值的數據,可以考慮使用稀疏數組來進行存儲,
這樣數據相對來說就會瘦小很多,不但可以節省磁盤空間,還可以優化磁盤讀寫時性能。