稀疏数组、队列
稀疏数组
稀疏数组介绍
- 当一个数组(包括多维数组)中大部分元素为0,或者为同一个值时,为了节约空间起到压缩的效果,将数据用另一种结构来表示,即稀疏数组。
稀疏数组压缩条件
- 1、原数组中存在大量的无效数据,占据了大量的存储空间,真正有用的数据很少;
- 2、压缩存储可以节省存储空间,避免资源的不必要浪费,在数据序列化到磁盘时,压缩存储可以提高IO效率;
数组压缩稀疏数组
- 1、记录数组的行数和列数,以及真实(有效)数据的个数;
- 2、记录有效数据在数组中的行列值及数值;
例:数组
\[\begin{matrix}
0&0&0&0\\
0&1&0&0\\
0&0&0&0\\
0&0&1&0\\
\end{matrix}\]
转换为稀疏数组:
\[\begin{matrix}
4&4&2\\
1&1&1\\
3&2&1\\
\end{matrix}\]
其中第一行记录系数数组的行数、列数以及有效值,其他行记录有效数据的行列数及数值。
示例代码:
//原数组--模拟数组
int[][] arr = new int[11][11];
arr[1][2]=1;
arr[2][4]=2;
//输出原数组-查看
for (int[] intArr:arr){
for (int intM : intArr){
System.out.printf("%d\t",intM);
}
System.out.println();
}
//查找原数组有效元素
int num = 0;
for (int i=0;i<11;i++){
for (int j=0;j<11;j++){
if (arr[i][j]!=0){
num ++;
}
}
}
System.out.println("原数组有效元素个数:"+num);
//定义稀疏数组--初始化0行
int[][] sparseArray = new int[num+1][3];
sparseArray[0][0]=11;
sparseArray[0][1]=11;
sparseArray[0][2]=num;
//定义行指针
int count = 0;
//稀疏数组有效数据
for (int i=0;i<11;i++){
for (int j=0;j<11;j++){
if (arr[i][j]!=0){
//有效元素
count++;
sparseArray[count][0]=i;
sparseArray[count][1]=j;
sparseArray[count][2]=arr[i][j];
}
}
}
//输出稀疏数组
for(int[] spArr:sparseArray){
for (int sp :spArr){
System.out.printf("%d\t",sp);
}
System.out.println();
}
运行结果:

稀疏数组转原数组
直接上代码:
//输出稀疏数组
System.out.println("稀疏数组:");
for (int[] spRow : sparseArr){
for (int spCol : spRow){
System.out.printf("%d\t",spCol);
}
System.out.println();
}
//定义原数组
int row = sparseArr[0][0];
int col = sparseArr[0][1];
int[][] arr = new int[row][col];
//填充有效数据
int count = 0;
for (int[] spRow : sparseArr){
count++;
if (count == 1){
continue;
}
arr[spRow[0]][spRow[1]]=spRow[2];
}
//输出原数组
System.out.println("原数组");
for (int[] arrRow : arr){
for(int arrCol : arrRow){
System.out.printf("%d\t",arrCol);
}
System.out.println();
}
运行结果

队列
队列介绍
- 队列是一种特殊的线性表,只允许在表的前端(队头)进行删除操作,尾端(队尾)进行插入操作,和栈一样,队列是一种操作受限的线性表;
- 队列是一个有序列表,可以用数组和链表实现;
- 队列先进先出,即先入队的数据最先被取出,后入队的数据最后被取出;
- 真溢出:入队存储的数据占满内存时,rear指针后移没有存储空间,为真溢出;
- 假溢出:队列数据出队时,front指针后移,当front=rear时,两个指针都指向队尾,存储空间虽然释放出来,但是存储不了数据;
- 循环队列:队列存储空间满时,入队的同时出队。
![]()
基于数组实现队列
直接上代码
/**
* 基于数组实现队列
*/
public class ArrayQueue {
//数组
private int[] array;
//队列大小
private int maxSize;
//队头指针
private int front;
//队尾指针
private int rear;
public ArrayQueue(int maxSize) {
this.maxSize = maxSize;
this.array = new int[this.maxSize];
front=rear=-1;
}
/**
* 是否为空队列
* @return
*/
public boolean isEmpty(){
return front==rear;
}
/**
* 是否为满队列
* @return
*/
public boolean isFull(){
return rear==maxSize-1;
}
/**
* 入队
* @param num
*/
public void add(int num){
if (isFull()){
System.out.println("队列已满!");
return;
}
rear++;
array[rear]=num;
System.out.println(">>>>>>>>>>>>"+num+" 入队>>>>>>>>>>>>>>>");
}
/**
* 出队
*/
public void del(){
if (isEmpty()){
System.out.println("队列为空队列!");
return;
}
front++;
System.out.println(">>>>>>>>>>>>>>>>>"+array[front]+" 出队>>>>>>>>>>>>>>>>>>>>");
array[front]=0;
}
/**
* 循环队列
*/
public void circleQueue(int num){
if (isFull()){
//出队 元素前移 入队
front=0;
System.out.println(">>>>>>>>>>>>>>>>>"+array[front]+" 出队>>>>>>>>>>>>>>>>>>>>");
for (int i=0;i<maxSize;i++){
if ((i+1)==maxSize){
continue;
}
array[i]=array[i+1];
}
array[rear]=num;
System.out.println(">>>>>>>>>>>>"+num+" 入队>>>>>>>>>>>>>>>");
}else {
rear++;
array[rear]=num;
System.out.println(">>>>>>>>>>>>"+num+" 入队>>>>>>>>>>>>>>>");
}
}
/**
* 查看队列元素
* @return
*/
public void queueArray(){
for (int num : array){
System.out.printf("%d\t",num);
}
System.out.println();
}
}
数据结构相关代码仓库地址:
https://gitee.com/red_leafzsp/structureAlgorithms

浙公网安备 33010602011771号