稀疏数组
简介
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组保存该数组
处理方法
- 记录数组共有几行几列,有多少不同的值
- 把具有不同指的元素的行列以及值记录在一个小规模的数组中,从而缩小程序的规模
二维数组转稀疏数组
- 遍历原始二维数组,得到有效数据的个数sum
- 根据sum就可以创建稀疏数组sparseArr int[sum+1][3]
- 将二维数组的有效数据存入到稀疏数组中
稀疏数组转二维数组
- 稀疏数组的第一行保存的原始数组的元数据,行列以及有效数据(有意义的数据),根据首行数据,创建原始的二维数组
- 在读取稀疏数组后几行的数据,并赋给原始的二维数组即可
原始数组转二维数组
public static void main(String[] args) {
//原始数据
int[][] orgArr = new int[11][10];
//添加数据
orgArr[1][2] = 2;
orgArr[2][3] = 4;
//统计有效数据
int sum = 0;
System.out.println("原始数组:");
for (int i = 0;i<orgArr.length;i++){
for (int j = 0;j<orgArr[i].length;j++){
System.out.print(String.format("%d\t",orgArr[i][j]));
if (!Objects.equals(0,orgArr[i][j]))
sum++;
}
System.out.println();
}
//原始数组转稀疏数组
int[][] sparseArr = new int[sum+1][3];
//记录原始数组的元数据
sparseArr[0][0] = orgArr.length;
sparseArr[0][1] = orgArr[0].length;
sparseArr[0][2] = sum;
//设置计数器
int folow = 1;
for (int i = 0;i<orgArr.length;i++){
for (int j = 0;j<orgArr[i].length;j++){
if (!Objects.equals(0,orgArr[i][j])){
sparseArr[folow][0] = i;
sparseArr[folow][1] = j;
sparseArr[folow][2] = orgArr[i][j];
if (Objects.equals(folow,sum))
break;
folow++;
}
}
}
System.out.println("稀疏数组:");
for (int i = 0;i<sparseArr.length;i++){
for (int j = 0;j<sparseArr[i].length;j++){
System.out.print(String.format("%d\t",sparseArr[i][j]));
}
System.out.println();
}
}
队列
介绍
- 队列是一个有序列表,可以用数组或者链表实现
- 遵循先入先出的原则:先存入的数据,要先取出来;后存入的数据后取出来
- 示意图:
class ArrayQueue{
//队列最大容量
private int maxSize;
//队列头部
private int front;
//队列尾部
private int rear;
//队列
private int[] arr;
//队列构造器
public ArrayQueue(int maxSize){
this.maxSize = maxSize;
arr = new int[maxSize];
//指向队列头的前一个位置
front = -1;
//队列最后一个数据
rear = -1;
}
//判断队列已满
public boolean isFull(){
return rear == maxSize-1;
}
//判断是否为空
public boolean isEmpty(){
return rear == front;
}
//添加数据
public void add(int num) {
if (isFull())
throw new RuntimeException("队列已满");
rear++;
arr[rear] = num;
}
//获取数据
public int get(){
if (isEmpty())
throw new RuntimeException("队列已经空了~");
front++;
return arr[front];
}
//展示数据
public void show(){
if (isEmpty()) {
System.out.println("队列为空!");
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.println(String.format("arr[%d]=%d/n",i,arr[i]));
}
}
//展示队列头部数据
public int showFront(){
if (isEmpty())
throw new RuntimeException("队列已经空了~");
return arr[front+1];
}
}
上述队列结构只能使用一次,不能做到重复使用
- 尾索引的下一个是头索引则表示队列已满,即将队列容量作为一个约定(rear+1)%maxSize =front 队列已满
- rear = front 队列为空
class CircleArrayQueue{
//队列最大容量
private int maxSize;
//front 变量含义:指向队列第一个元素 front初始值尾0
private int front;
//rear指向最后一个元素的后一个位置 rear初始值尾0
private int rear;
//队列
private int[] arr;
//初始化
public CircleArrayQueue(int maxSize){
this.maxSize = maxSize;
front = 0;
rear = 0;
arr = new int[maxSize];
}
//队列是否满了
public boolean isFull(){
return (rear+1)%maxSize == front;
}
//判断数据是否为空
public boolean isEmpty(){
return rear == front;
}
//添加数据
public void add(int n){
if (isFull())
throw new RuntimeException("队列已满");
arr[rear] = n;
rear = (rear+1) % maxSize;
}
//获取数据
public int get(){
if (isEmpty())
throw new RuntimeException("队列已空");
//获取当前第一个变量值
int value = arr[front];
//将front后移
front = (front+1) % maxSize;
return value;
}
//获取有效数据的小标
public int size(){
return (rear + maxSize- front) % maxSize;
}
}