Artigo Diretório
Título 1: O conceito de fila
Uma fila é uma lista ordenada e pertence a uma estrutura linear, que pode ser implementada como uma matriz ou uma lista vinculada.
Princípio: Primeiro a
entrar , primeiro a sair Fila unidirecional: Apenas uma extremidade pode ser enfileirada ou retirada da
fila Fila circular: Ambas as extremidades podem ser implementadas.
Título 2: Operação de fila unilateral
Ideia: primeiro declare a matriz, maxSize é o índice da capacidade máxima da fila, ou seja, maxSize-1, porque o subscrito da matriz começa em 0. Após as filas traseira e frontal, o valor inicial é -1, traseiro Ele muda com a entrada de dados e a frente muda com a saída de dados. Você pode entender isso olhando para a foto.
Analise as condições de a fila estar cheia e vazia:
cheia: obviamente quando traseira = MaxSize-1 está cheia
Vazia: traseira = frente está vazia
Vamos analisar o código
package queue;
import java.util.Scanner;
public class ArrayQueueDemo {
public static void main(String[] args) {
//测试一把
// 创建一个队列
BrrayQueue queue = new BrrayQueue(3);
char key = ' ';// 接收用户输入
Scanner scanner = new Scanner(System.in);
boolean loop = true;
//输出一个菜单
while (loop) {
System.out.println("s(show): 显示队列");
System.out.println("e(exit): 退出程序");
System.out.println("a(add): 添加数据到队列");
System.out.println("g(get): 从队列取出数据");
System.out.println("h(head): 查看队列头的数据");
key = scanner.next().charAt(0);//接收一个字符
switch(key)
{
case 's':
queue.showQueue();
break;
case 'a':
System.out.println("输出一个数");
int values=scanner.nextInt();
queue.addQueue(values);
break;
case 'g':
try
{
int res=queue.getQueue();
System.out.printf("取出来的数据是%d",res);
}catch(Exception e)
{
System.out.println(e.getMessage());
}
System.out.println();
break;
case 'h':
try
{
int res=queue.headQueue();
System.out.printf("取出来的数据是%d",res);
}catch(Exception e)
{
System.out.println(e.getMessage());
}
System.out.println();
break;
case 'e'://退出
scanner.close();
loop=false;
break;
default:
break;
}
}
System.out.println("exit!");
}
}
class BrrayQueue
{
private int maxSize;
private int front;
private int rear;
private int[] arr;
public BrrayQueue(int arrMaxSize)
{
maxSize=arrMaxSize;
arr=new int[maxSize];
front=-1;
rear=-1;
}
//判断队列是否满
public boolean isFull()
{
return rear==maxSize-1;
}
//判断队列是否为空
public boolean isEmpty()
{
return rear==front;
}
//添加数据到队列
public void addQueue(int n)
{
//判断队列是否满
if(isFull())
{
System.out.println("队列已满,不能加入数据");
return;
}
rear++;
arr[rear]=n;
}
//获取数据出队列
public int getQueue()
{
//判断队列是否为空
if(isEmpty())
{
//通过抛出异常处理
throw new RuntimeException("队列为空!");
}
front++;
return arr[front];
}
//显示队列的所有数据
public void showQueue()
{
//遍历
if(isEmpty())
{
System.out.println("队列为空!");
return;
}
for(int i=0;i<arr.length;i++)
{
System.out.printf("arr[%d]=%d/n",i,arr[i]);
}
}
//显示队列的头数据
public int headQueue()
{
if(isEmpty())
{
throw new RuntimeException("对列为空");
}
return arr[front+1];
}
}
/**
* break 跳出总上一层循环,不再执行循环(结束当前的循环体)
* continue 跳出本次循环,继续执行下次循环(结束正在执行的循环 进入下一个循环条件)
* return 程序返回,不再执行下面的代码(结束当前的方法 直接返回)
*/
Eu acredito que irmãos podem entender isso!
Título 3: Operação da fila circular (é preciso entender)
A frente aponta para o primeiro elemento da fila e a parte traseira aponta para o segundo bit após o último elemento, e ambos têm um valor inicial de 0. Pense cuidadosamente sobre a diferença com a fila unilateral.
Princípio da fila circular: Na verdade, não há nenhuma circular na memória, então a fila circular é realmente realizada no espaço linear do array.
Quando a retaguarda retorna à posição 0, a operação de retorno é realizada por módulo, ou seja, o alinhamento circular é realizado por módulo.
Primeiro, vamos falar sobre módulo: Por exemplo, se qualquer número% 8, o resultado após o módulo está entre 0 e 8.
A equipe está cheia: Sua expressão é (traseira + 1)% maxSize = frente.
Dê uma olhada na minha análise: Quando traseira <maxSize-1, o módulo é para nada! ! !
Faça um desenho para entender que
você quer d entrar para a equipe nesse momento, ele é o último elemento, certo, então qual é o valor de retaguarda + 1? Ele transborda, excede o tamanho da matriz, mas nossa fila não está cheia neste momento e podemos inseri-la antes. Neste momento, podemos imaginar a matriz como um anel. Então, o índice após d é 0. Junte-se à equipe com um e, na foto acima.
Neste momento, a retaguarda aponta para 1, então podemos adicionar outros dados?
Se for possível, a parte traseira apontará para 2, desta vez traseira = dianteira, e esta condição é precisamente a condição de que a fila está vazia. É o mesmo que a fila está cheia. Neste momento, não é possível julgar se ela está vazia ou cheia. Portanto, temos que deixar a última posição do último elemento como um acordo para não inserir dados, apenas para julgar se está vazia ou cheia.
Neste momento, a condição completa é (traseiro + 1)% maxSize = frente, e
esta expressão já liberou um espaço para acordo. Pense bem e compare a imagem.
Assim como quando traseiro = 1, maxSize = 6; traseiro + 1 = 2% maxSize = 2% 6 = 2 = frente. Nesse momento, a fila está cheia e vazia. A posição apontada por trás é 1, e o índice anterior é O elemento 0 é o último dado, o índice 1 é a convenção.
Um problema com a fila unilateral é que quando rear = maxSize, o programa pensará erroneamente que ela está cheia, então não pode continuar a ser inserida.Esta fila unidirecional só pode ser usada uma vez.
A fila circular também resolve esse problema.Neste momento, a capacidade de dados que a fila circular pode armazenar é maxSize,
mas quantos dados eficazes ela tem?
Frente traseira?
Isso deve estar errado porque se trata de um anel, e a parte traseira pode ser menor que a dianteira. Neste momento, não dê por nada! !
A expressão correta (traseiro-frontal + maxSize)% maxSize
explica:
Meu próprio entendimento: traseiro-frontal é a distância entre a cabeça e o final da equipe, números negativos não são considerados, porque a distância não pode ser negativa. Adicionar maxSize e depois tirar o módulo não é um dado válido. Pode ser entendido em conjunto com a operação do módulo. Neste momento, o módulo é remover a distância entre a cabeça e o final da equipe, que não é válida.
Neste momento, você sabe que não pode usar o rear ++, basta pegar o módulo.
Neste momento traseiro = (traseiro + 1)% maxSize, frontal = (frontal + 1)% maxSize
cole o código abaixo para entender:
package queue;
import java.util.Scanner;
public class CircleArrayQqueue {
public static void main(String[] args) {
//测试一把
// 创建一个队列
CircleArray queue = new CircleArray(4);
char key = ' ';// 接收用户输入
Scanner scanner = new Scanner(System.in);
boolean loop = true;
//输出一个菜单
while (loop) {
System.out.println("s(show): 显示队列");
System.out.println("e(exit): 退出程序");
System.out.println("a(add): 添加数据到队列");
System.out.println("g(get): 从队列取出数据");
System.out.println("h(head): 查看队列头的数据");
key = scanner.next().charAt(0);//接收一个字符
switch(key)
{
case 's':
queue.showQueue();
break;
case 'a':
System.out.println("输出一个数");
int values=scanner.nextInt();
queue.addQueue(values);
break;
case 'g':
try
{
int res=queue.getQueue();
System.out.printf("取出来的数据是%d",res);
}catch(Exception e)
{
System.out.println(e.getMessage());
}
System.out.println();
break;
case 'h':
try
{
int res=queue.headQueue();
System.out.printf("取出来的数据是%d",res);
}catch(Exception e)
{
System.out.println(e.getMessage());
}
System.out.println();
break;
case 'e'://退出
scanner.close();
loop=false;
break;
default:
break;
}
}
System.out.println("exit!");
}
}
class CircleArray
{
private int maxSize;
private int front;
private int rear;
private int[] arr;
public CircleArray(int arrMaxSize)
{
maxSize=arrMaxSize;
arr=new int[maxSize];
front=0;//默认是0
rear=0;
}
//判断队列是否满
public boolean isFull()
{
return (rear + 1) % maxSize == front;
}
//判断队列是否为空
public boolean isEmpty()
{
return rear==front;
}
//添加数据到队列
public void addQueue(int n)
{
//判断队列是否满
if(isFull())
{
System.out.println("队列已满,不能加入数据");
return;
}
//直接将数据加入
arr[rear] = n;
//将 rear 后移, 这里必须考虑取模
rear = (rear + 1) % maxSize;
}
//获取数据出队列
public int getQueue()
{
//判断队列是否为空
if(isEmpty())
{
//通过抛出异常处理
throw new RuntimeException("队列为空!");
}
// 这里需要分析出 front 是指向队列的第一个元素
// 1. 先把 front 对应的值保留到一个临时变量,如果不保存return arr[front]此时直接从第二个元素 开始出因为front初始值为0.
// 2. 将 front 后移, 考虑取模
// 3. 将临时保存的变量返回
int value = arr[front];
front = (front + 1) % maxSize;
return value;
}
//显示队列的所有数据
public void showQueue()
{
//遍历
if(isEmpty())
{
System.out.println("队列为空!");
return;
}
for (int i = front; i < front + size() ; i++)
{
System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);
}
}
// 求出当前队列有效数据的个数
public int size()
{
// rear = 2 // front = 1 // maxSize = 3
return (rear + maxSize - front) % maxSize;
}
//显示队列的头数据
public int headQueue()
{
if(isEmpty())
{
throw new RuntimeException("对列为空");
}
return arr[front];
}
}
Entendimento pessoal, por favor me ajude, siga-me ou comente, hahaha.