1.稀疏数组介绍
当一个数组中大部分元素是0,或为同一个值的时候,可以使用稀疏数组来保存数组。它是一个十分有效的存储结构,便于节省存储空间。
2.示意图
3.以上二维数组的缺点:
原数组中存在大量的无效数据,占据了大量的存储空间,真正有用的数据很少
4.稀疏数组处理方法:
- 记录数组一共有几行几列,有多少个不同的值
- 把具有不同值元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模。
5.实现步骤:
6.具体应用:
-
使用稀疏数组来保留如上二维数组(棋盘)
- 把稀疏数组存盘可以重新恢复原来的二维数组
7.代码实现:
- 一维数组
package array;
/**
* @author WuChenGuang
*/
public class SparseArray {
public static void main(String[] args) {
// 1.模拟出来棋盘数据,使用二维数组
int num = 11;
int[][] array = new int[num][num];
array[1][2] = 1;
array[2][4] = 2;
// 打印棋盘查看效果
for (int[] row : array) {
for (int val : row) {
System.out.printf("%d\t", val);
}
System.out.println();
}
// 需要把如上的二维数组中有效数据压缩至稀疏数组中去
// 计算二维数组中有效数据
int sum = 0;
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
if (array[i][j] != 0) {
sum++;
}
}
}
// 定义稀疏数组
int[][] sparseArray = new int[sum + 1][3];
// 行
sparseArray[0][0] = 11;
// 列
sparseArray[0][1] = 11;
// 有效数据个数
sparseArray[0][2] = sum;
// 把有效数据存放至稀疏数组中去
int count = 0;
// 行的索引
for (int i = 0; i < num; i++) {
// 列的索引
for (int j = 0; j < num; j++) {
// 判断是否是有效数据
if (array[i][j] != 0) {
count++;
sparseArray[count][0] = i;
sparseArray[count][1] = j;
sparseArray[count][2] = array[i][j];
}
}
}
// 打印稀疏数组
for (int[] ints : sparseArray) {
// System.out.printf("%d,%d,%d\t", ints[0], ints[1], ints[2]);
System.out.println(ints[0] + " " + ints[1] + " " + ints[2]);
}
// 把稀疏数组转原始二维数组(面试题)
int[][] oldArray = new int[sparseArray[0][0]][sparseArray[0][1]];
for (int i = 1; i <= count; i++) {
oldArray[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
}
System.out.println("========================================");
// 原始二维数组棋盘
for (int[] row : oldArray) {
for (int val : row) {
System.out.printf("%d\t", val);
}
System.out.println();
}
}
}
运行结果:
- 单向链表
package array;
/**
* @author WuChenGuang
* 模拟结点
*/
public class SingleNode {
/**
* row 行号
* column 列号
* num 值
*/
public int row;
public int column;
public int num;
/**
*next域:指向下一个结点
*/
public SingleNode next;
public SingleNode(int row, int column, int num) {
this.row = row;
this.column = column;
this.num = num;
}
@Override
public String toString() {
return "SingleNode{" +
"row=" + row +
", column=" + column +
", num=" + num +
", next=" + next +
'}';
}
}
package array;
/**
* @author WuChenGuang
*/
public class SingleLinkList {
/**
* 头节点
*/
private final SingleNode headSingleNode;
/**
* 通过构造行数初始化头节点
* @param headSingleNode 头节点
*/
public SingleLinkList(SingleNode headSingleNode) {
this.headSingleNode = headSingleNode;
}
/**
* 添加结点(追加在链表的尾端)
*/
public void add(SingleNode singleNode){
SingleNode temp = headSingleNode;
// 如果这个结点的next域为空就跳出while循环
while (temp.next != null) {
// 将下一个结点赋值给temp
temp = temp.next;
}
temp.next= singleNode;
}
/**
* 遍历单项链表
*/
public void show(){
if (headSingleNode.next == null) {
System.out.println("当前链表为空");
return;
}
SingleNode temp = headSingleNode;
while (temp.next != null) {
temp = temp.next;
System.out.println(temp);
}
}
/**
* 将链表还原成二维数组
* @return array还原后的二维数组
*/
public int[][] backToArray(){
SingleNode temp = headSingleNode;
// 头结点中存储着原数组的行数和列数
// 通过这两个值创建二维数组
int[][] array = new int[headSingleNode.row][headSingleNode.column];
while (temp.next != null) {
temp = temp.next;
// 每遍历一个结点就还原一个数据
array[temp.row][temp.column] = temp.num;
}
return array;
}
}
package array;
/**
* @author WuChenGuang
*/
public class SparseArray2 {
public static void main(String[] args) {
// 1.模拟出来棋盘数据,使用二维数组
int[][] array = new int[4][5];
// 初始化二维数组
array[0][2] = 1;
array[1][1] = 2;
array[2][3] = 3;
System.out.println("========普通数组========");
// 遍历二维数组
int count = 0;
for (int[] ints : array) {
for (int anInt : ints) {
if (anInt != 0) {
count++;
}
System.out.print(anInt + " ");
}
System.out.println();
}
// 将数组转化成链式存储
SingleLinkList list = new SingleLinkList(new SingleNode(array.length, array[0].length, count));
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
if (array[i][j] != 0) {
//当数字不为0时视为有效值就创建一个结点并添加到链表尾部
list.add(new SingleNode(i, j, array[i][j]));
}
}
}
System.out.println("========转化后的链表========");
// 遍历单向链表
list.show();
int[][] returnArray = list.backToArray();
//遍历还原后的二维数组
System.out.println("========还原后的数组========");
for (int[] ints : returnArray) {
for (int anInt : ints) {
System.out.print(anInt + " ");
}
System.out.println();
}
}
}
运行结果: