稀疏数组
稀疏数组的定义
- 当一个数组中大部分元素是0,或者为同一值的数组时,可以使用稀疏数组保存该数组
- 稀疏数组的处理方式是首行记录数组一共有几行几列,有多少个值不同
- 把具有不同值得元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
稀疏数组的结构
- 稀疏数组固定有三列
- 首行记录 有几行 几列 几个有效值 (也就是二维数组的空间)所以一般转化成稀疏数组的时候 定义的一维空间是有效值+1
- 从第二行开始记录有效值的具体坐标 哪行 哪列 有效值
- 如图:
练习:稀疏数组要求有存盘 和 续上盘的功能
1.将棋盘用二维数组表示/创建一个二维数组5*5
- 棋盘就是 行 列 组成的二维数组 由于未定义的元素默认值是0所以 可以理解成 0是没有下的格子 有效值为已下的棋子1是黑棋 2是白棋
- 将有效值赋值利用下标精确赋值
int[][]array1=new int[5][5];
array1[0][2]=1;
array1[1][2]=2;
array1[3][4]=1;
这样就得到了一个二维数组
2.将二维数组转化为稀疏数组保存
- 首先测算出有效值是多少个
int sum=0;//定义一个sum用于储存
for (int[] i : array1) {
for (int j : i) {//将二维数组的每个下标都走一遍
if (j!=0){//如果当前小标不=0
sum++;//那么就是有效值 sum自增1
}
}
}System.out.println("有效个数值为:"+sum);//当走完全部也就得到了有效值的个数
- 新建一个二维数组:稀疏数组
int[][]array2=int[sum+1][3];//因为 是从第二行才开始记录有效值 所以定义空间是 行要在有效值的数量上+1 列是稀疏数组的固定列
- 定义稀疏数组的首行 (概况 总结 记录了 几行 几列 有效值是多少个)
array2[0][0]=5;//记录二维数组的行
array2[0][1]=5;//记录二维数组的列
array2[0][2]=sum;//记录二维数组的有效值
- 将有效值赋值记录到稀疏数组当中 格式(行 列 值)
int count=0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1.length; j++) {
if (array1[i][j]!=0){//当前小标的值不为0时就是有效值
count++;//cuunt+1每找到一个有效值 就加一行 并且可在下面的运行中当作当前第几行(相当于新创建一行来记录 具体 行列值)
array2[count][0]=i;//当前的行
array2[count][1]=j;//当前的列
array2[count][2]=array1[i][j];//当前的值,利用二位数组的下标进行赋值
- 输出这个稀疏数组
就得到了:
3.将稀疏数组还原成普通二维数组 也就是棋盘
- 首先创建一个新的二维数组 这个新数组的空间可以读取稀疏数组的首行 确认行 列 进行定义
int[][]array3=new int[array2[0][0]][array2[0][1]];
- 读取稀疏数组的元素保存行 赋值到新数组的指定下标
for (int i = 1; i <array2.length; i++) {//注意由于第一行 下标[0]是稀疏数组概况 保存的元素要从第二行[1]开始
array3[array2[i][0]][array2[i][1]]=array2[i][2];//看不懂可以debug代入脑子模拟一下
- 输出还原后的普通二维数组
for (int[] ints : array3) {
for (int anInt : ints) {
System.out.print(anInt+"\t");
}
System.out.println();
}
就得到了
完整代码实例
public static void main(String[] args) {
//T:稀疏数组 要求:有存盘和续上盘的功能
//1.创建一个维数组 5*5
int[][]array1=new int[5][5];
array1[0][2]=1;
array1[1][2]=2;
array1[3][4]=1;
//输出这个二维数组
for (int[] i : array1) {
for (int j : i) {
System.out.print(j+"\t");
}
System.out.println();
}System.out.println("==========================================");
//2.转换为稀疏数组保存
//获取有效值的个数
int sum=0;
for (int[] i : array1) {
for (int j : i) {
if (j!=0){
sum++;
}
}
}System.out.println("有效个数值为:"+sum);
//遍历一个稀疏数组的数组,创建第一行这个稀疏数组本身的定义 可以理解为概况 或者标签
//因为二位数组的组成是首行:记载 几行 几列 几个有效值,第二行开始记载有效值的具体坐标,所以sum+1需要将记载行加上1行,3是稀疏数组的固定记载列
int[][]array2=new int[sum+1][3];
array2[0][0]=5;
array2[0][1]=5;
array2[0][2]=sum;
//遍历二位数组,将有效的值,存放到稀疏数组中,利用行 列 值 模式存放
int count=0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1.length; j++) {
if (array1[i][j]!=0){
count++;
//这里的count++代表着 每找到一个有效值 就加一行 并且可在下面的运行中当作当前第几行(相当于新创建一行来记录 具体 行列值)
array2[count][0]=i;//当前的行
array2[count][1]=j;//当前的列
array2[count][2]=array1[i][j];//当前的值,利用二位数组的下标进行赋值
}
}
}//输出稀疏数组
for (int x = 0; x < array2.length; x++) {
for (int y = 0; y < array2[x].length; y++) {
System.out.print(array2[x][y]+"\t");
}System.out.println();//换行命令
}
System.out.println("======================================");
//3.读取稀疏数组 还原成原来的二位数组
//创建一个新二维数组,新二维数组的空间可以读取稀疏数组里保存的空间 几行 几列
int[][]array3=new int[array2[0][0]][array2[0][1]];
//读取稀疏数组的有效值并且赋值到新二维数组的指定位置
for (int i = 1; i <array2.length; i++) {//注意由于第一行 下标[0]是稀疏数组概况 保存的元素要从第二行[1]开始
array3[array2[i][0]][array2[i][1]]=array2[i][2];
}//输出还原后的二维数组
for (int[] ints : array3) {
for (int anInt : ints) {
System.out.print(anInt+"\t");
}
System.out.println();
}
}