JAVA数据结构与算法之稀疏数组

  • 前言:
    *数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率

稀疏数组

稀疏数组简介:

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

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

012
原始数组行数原始数组列数有效数据个数
有效数据所在行有效数据所在列有效数据
  • 文字描述
  1. 第一行存储原始数据总行数,总列数,总的有效数据个数
  2. 接下来每一行都存储有效数据所在行,所在列和具体值
  • 图示
    原始数组:
01234
001020
100020
211000
300020
400000
500000
600000

稀疏数组:

0 (行数)1 (列数)2 (有效数据)
05 (总行数)4 (总列数)6 (有效数据个数)
1011
2032
3132
4101
5111
6242

代码实现:

  • 二维数组转换为稀疏数组
  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 Lansion
 * @version 1.1
 * @since 1.0
 */
public class SparseArray {

	private 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)) ? "两数组相同" : "两数组不相同");
	}

}
  • 运行结果
    运行结果运行结果
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值