JAVA数据结构之稀疏数组

稀疏数组

稀疏数组简介:

  • 当一个数组中大部分数据均为0(均为同一个数值) 时,可以用稀疏数组来保存该数组
  • 压缩存储(保留有效数据) 可以节省存储空间以避免资源的不必要的浪费

存储方式(非链式存储):

0 1 2
原始数组行数 原始数组列数 有效数据个数
有效数据所在行 有效数据所在列 有效数据
  • 文字描述
  1. 第一行存储原始数据总行数,总列数,总的有效数据个数
  2. 接下来每一行都存储有效数据所在行,所在列和具体值
  • 图示
    原始数组:
0 1 2 3 4
0 0 1 0 2 0
1 0 0 0 2 0
2 1 1 0 0 0
3 0 0 0 2 0

稀疏数组:

0 (行数) 1 (列数) 2 (有效数据)
0 5 (总行数) 4 (总列数) 6 (有效数据个数)
1 0 1 1
2 0 3 2
3 1 3 2
4 1 0 1
5 1 1 1
6 2 4 2

代码实现:

  • 二维数组转换为稀疏数组
  1. 得到原始数组的行列数
  2. 遍历原始数组得到有效数据个数
  3. 创建稀疏数组并对稀疏数组进行赋值
    (1)对稀疏数组第一行进行赋值(原始数组的总行数,总列数,总的有效数据个数
    (2)遍历原始数组将有效数据及其对应位置放入稀疏数组
/**
	 * 
	 * <pre>
	 * 将数组转换为稀疏数组
	 * </pre>
	 * 
	 * @param array   原始数组
	 * @param invalid 无效数据
	 * @return 稀疏数组
	 */
	public static int[][] toSparseArray(int[][] array, int invalid) {
		int sum = 1, row = array.length, col = array[0].length;

		// 1.遍历初始数组,得到有效数据个数
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				if (array[i][j] != invalid)
					sum++;
			}
		}

		// 2.创建对应的稀疏数组
		int[][] sparseArr = new int[sum][3];
		// 给稀疏数组赋值
		sparseArr[0][0] = row;
		sparseArr[0][1] = col;
		sparseArr[0][2] = sum - 1;
		// 将有效数据放入稀疏数组
		int count = 0;
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				if (array[i][j] != invalid) {
					count++;
					sparseArr[count][0] = i;
					sparseArr[count][1] = j;
					sparseArr[count][2] = array[i][j];

				}
			}
		}
		return sparseArr;
	}

  • 稀疏数组转换为二维数组
  1. 根据稀疏数组的第一行创建原始数组
  2. 将稀疏数组中的数据还原到原始数组
	/**
	 * <pre>
	 * 将稀疏数组还原
	 * 无效数据还原成0
	 * </pre>
	 * 
	 * @param sparseArr 稀疏数组
	 * @return 恢复后的数组
	 */
	public static int[][] toArray(int[][] sparseArr) {
		// 1.创建原始数组
		int[][] array = new int[sparseArr[0][0]][sparseArr[0][1]];
		// 2.还原数据
		for (int i = 1; i <= sparseArr[0][2]; i++) {
			array[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
		}
		return array;
	}

完整程序测试:

  • 测试数据
    原始矩阵:
    00000000000
    00000100000
    00000010000
    00000020000
    00000000000
    00000000100
    00000000001
    00000000000
    00000000000
    00002000000
    00000200000
  • 结果预测
    11 11 7
    1 5 1
    2 6 1
    3 6 2
    5 8 1
    6 10 1
    9 4 2
    10 5 2
  • 程序代码
package DataStructures.linear.sparseArray;

/**
 * 
 * <pre>
 * 稀疏数组
 * 压缩存储(保留有效数据)可以节省存储空间以避免资源的不必要的浪费
 * </pre>
 * 
 * <pre>
 * 非链式存储方式
 * 第一行存储原始数据总行数,总列数,总的非0数据个数
 * 接下来每一行都存储有效数据所在行,所在列,和具体值
 * </pre>
 * 
 * @author Lasion
 * @version 1.1
 * @since 1.0
 */
public class SparseArray {

	public SparseArray() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * <pre>
	 * 将数组转换为稀疏数组
	 * 默认无效数据为0
	 * </pre>
	 * 
	 * {@link SparseArray#toSparseArray(int[][], int)}
	 */
	public static int[][] toSparseArray(int[][] array) {
		return toSparseArray(array, 0);
	}

	/**
	 * 
	 * <pre>
	 * 将数组转换为稀疏数组
	 * </pre>
	 * 
	 * @param array   原始数组
	 * @param invalid 无效数据
	 * @return 稀疏数组
	 */
	public static int[][] toSparseArray(int[][] array, int invalid) {
		int sum = 1, row = array.length, col = array[0].length;

		// 1.遍历初始数组,得到有效数据个数
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				if (array[i][j] != invalid)
					sum++;
			}
		}

		// 2.创建对应的稀疏数组
		int[][] sparseArr = new int[sum][3];
		// 给稀疏数组赋值
		sparseArr[0][0] = row;
		sparseArr[0][1] = col;
		sparseArr[0][2] = sum - 1;
		// 将有效数据放入稀疏数组
		int count = 0;
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < col; j++) {
				if (array[i][j] != invalid) {
					count++;
					sparseArr[count][0] = i;
					sparseArr[count][1] = j;
					sparseArr[count][2] = array[i][j];

				}
			}
		}
		return sparseArr;
	}

	/**
	 * <pre>
	 * 将稀疏数组还原
	 * 无效数据还原成0
	 * </pre>
	 * 
	 * @param sparseArr 稀疏数组
	 * @return 恢复后的数组
	 */
	public static int[][] toArray(int[][] sparseArr) {
		// 1.创建原始数组
		int[][] array = new int[sparseArr[0][0]][sparseArr[0][1]];
		// 2.还原数据
		for (int i = 1; i <= sparseArr[0][2]; i++) {
			array[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];
		}
		return array;
	}

	/**
	 * <pre>
	 * 两数组是否相等
	 * </pre>
	 * 
	 * @param array
	 * @param sparseArr
	 * @return 两数组相等->true
	 */
	private static boolean equal(int[][] array, int[][] sparseArr) {
		for (int i = 0; i < array.length; i++) {
			for (int j = 0; j < array[0].length; j++) {
				if (array[i][j] != sparseArr[i][j])
					return false;
			}
		}
		return true;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[][] a = new int[11][11];
		a[1][5] = 1;
		a[3][6] = 2;
		a[2][6] = 1;
		a[6][10] = 1;
		a[10][5] = 2;
		a[5][8] = 1;
		a[9][4] = 2;
		System.out.println("原始数组:");
		for (int[] is : a) {
			for (int n : is)
				System.out.print(n);
			System.out.println();
		}

		System.out.println("-----------------------------");
		int[][] s = toSparseArray(a);
		System.out.println("稀疏数组:");
		for (var is : s) {
			for (var n : is)
				System.out.print(n + "  ");
			System.out.println();
		}

		System.out.println("-----------------------------");
		int[][] b = toArray(s);
		System.out.println("还原后的数组:");
		for (var is : b) {
			for (var n : is)
				System.out.print(n);
			System.out.println();
		}

		System.out.println("-----------------------------");
		System.out.println((equal(a, b)) ? "两数组相同" : "两数组不相同");
	}

}
  • 运行结果
    运行结果运行结果
发布了1 篇原创文章 · 获赞 0 · 访问量 42

猜你喜欢

转载自blog.csdn.net/weixin_43905191/article/details/104317326