fila de implementação de array java (fila unidirecional e fila circular)

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.
Insira a descrição da imagem aqui
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
Insira a descrição da imagem aquivocê 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.

Insira a descrição da imagem aquiNeste 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.

Acho que você gosta

Origin blog.csdn.net/qq_42678668/article/details/106210964
Recomendado
Clasificación