Estrutura de dados JAVA-2. Implementação de filas ordinárias e filas circulares e análise do uso de fila JAVA

Estrutura de dados e algoritmo

2. Fila

Fila é uma lista ordenada que pode ser implementada com uma matriz ou uma lista vinculada.

Siga o princípio do primeiro a entrar, primeiro a sair.

Insira a descrição da imagem aqui

Ideias de implementação (fila comum)

  1. Ao usar a estrutura de uma matriz para implementar uma fila, crie uma classe que contenha uma fila de objetos de matriz e, ao mesmo tempo, maxSize é necessário para indicar a capacidade máxima da fila;
  2. Como a entrada e a saída da fila são processadas separadamente da parte frontal e posterior, duas variáveis ​​frontais e traseiras são necessárias para registrar os subscritos das extremidades frontal e posterior da fila, respectivamente. A frente mudará com a saída de dados e a parte traseira mudará com a entrada de dados;
    1. Entre eles, frente aponta para a posição anterior do primeiro objeto na fila .
    2. a retaguarda aponta para o fim da fila.
  3. O método addQueue na classe de escrita indica que a fila foi adicionada:
    1. Mova o ponteiro da cauda para trás para trás: traseiro + 1; quando dianteiro == traseiro (a fila está vazia).
    2. Se o ponteiro da cauda movido for menor que o subscrito máximo maxSize-1 da fila (o subscrito começa em 0), os dados são armazenados no elemento da matriz apontado por trás, caso contrário, os dados não podem ser armazenados (retaguarda == maxSeize-1, a fila está cheia )
  4. O método removeQueue na classe de escrita significa remover a fila:
    1. Quando a fila não estiver vazia, mova o ponteiro principal uma posição para a frente para encontrar o primeiro número na fila.

Implementação de código (fila normal)

public class ArrayQueue {
    
    
    public  static void main(String args[]){
    
    
    }
}

class ArrayQueueClass{
    
    
    private int maxSize;
    private int front;
    private int rear;
    private int[] arr;
    public ArrayQueueClass(int arrMaxSize){
    
    
        this.maxSize = arrMaxSize;
        front = -1;
        rear = -1;
        arr = new int[arrMaxSize];
    }

    public boolean isEmpty(){
    
    
        if(front == rear){
    
    
            return true;
        }
        return false;
    }

    public boolean isFull(){
    
    
        if(rear == maxSize-1){
    
    
            return true;
        }
        return false;
    }

    public void addQueue(int data){
    
    
        if(isFull()){
    
    
            throw new RuntimeException("队列已经满了~");
        }
        rear++;
        arr[rear] = data;
    }

    public int removeQueue(){
    
    
        if(isEmpty()){
    
    
            throw  new RuntimeException("队列为空,无法取数据");
        }
        front++;
        return arr[front];
    }
    public void showQueue(){
    
    
        if(isEmpty()){
    
    
            throw  new RuntimeException("队列为空");
        }
        for (int i = front+1; i <= rear ; i++) {
    
    
            System.out.printf("%d\t",arr[i]);
        }
        System.out.println();
    }

    public int check(){
    
    
        if(isEmpty()){
    
    
            throw  new RuntimeException("队列为空");
        }

        return arr[front+1];
    }

}

Problema: O ponteiro continua aumentando e a matriz não pode ser usada depois de usada, e o efeito de reutilização não é alcançado.

Solução: Mude a matriz para uma matriz circular e use o módulo para alcançar

Ideias de implementação (fila circular)

  1. O significado da variável front é ajustado, front aponta para o primeiro elemento da fila, arr [front] é o primeiro elemento da fila e o valor inicial de front é 0
  2. O conteúdo da variável traseira é ajustado, traseira aponta para a última posição do último elemento da fila, porque espera-se que um espaço seja deixado por convenção. Neste momento, a capacidade máxima utilizável da fila é maxSize-1, e o valor inicial de rear é 0;
  3. Quando a fila está cheia, a condição é (traseiro + 1)% maxSize == frente
  4. Quando a fila está vazia, traseira == frente
  5. O número de dados válidos na fila é (traseiro + maxSize -frotn)% maxSize

Implementação de código (fila circular)

public class CircleArrayQueueDemo {
    
    
    public  static void main(String args[]){
    
    
        CricleArrayQueue queue = new CricleArrayQueue(4);   //此时可以用队列为3
        queue.addQueue(0);
        queue.showQueue();
        queue.addQueue(1);
        queue.showQueue();
        queue.addQueue(2);
        queue.showQueue();
//        queue.addQueue(3); //java.lang.RuntimeException: 队列已经满了~  front==0  rear==3

        System.out.println(queue.removeQueue());
        queue.showQueue();
        System.out.println(queue.removeQueue());
        queue.showQueue();
        System.out.println(queue.removeQueue());
        System.out.println();
//        queue.showQueue();//java.lang.RuntimeException: 队列为空  front == rear ==3

        queue.addQueue(4);  //front ==3  rear ==0
        queue.showQueue();
        queue.addQueue(5); //front ==3  rear ==1

        System.out.println(queue.removeQueue());//front ==0  rear ==1
        System.out.println(queue.removeQueue());//front ==1  rear ==1

    }
}
class CricleArrayQueue{
    
    
    private int maxSize;
    public int front;
    public int rear;
    private int[] arr;
    public CricleArrayQueue(int arrMaxSize){
    
    
        this.maxSize = arrMaxSize;
        front = 0;  //front表示指向第一个元素 取元素时先取再+1
        rear = 0;   //rear表示指向最后一个元素的后一个位置  加元素时先加元素在+1
        arr = new int[arrMaxSize];  //设置队列最大长度,此时保留一个位置作为队列满的判断,因此最大可用数量为maxSize-1
    }
    public boolean isEmpty(){
    
    
        if(front == rear){
    
    
            return true;
        }
        return false;
    }

    public boolean isFull(){
    
    
        if((rear+1)%maxSize == front){
    
    
            return true;
        }
        return false;
    }
    public void addQueue(int data){
    
    
        if(isFull()){
    
    
            throw new RuntimeException("队列已经满了~");
        }
        arr[rear] = data;
        rear = (rear+1)%maxSize;
    }
    public int removeQueue(){
    
    
        if(isEmpty()){
    
    
            throw  new RuntimeException("队列为空,无法取数据");
        }
        int value = arr[front];
        front = (front+1)%maxSize;
        return value;
    }
    public void showQueue(){
    
    
        if(isEmpty()){
    
    
            throw  new RuntimeException("队列为空");
        }
        for (int i = front; i < front+ (rear - front + maxSize)%maxSize; i++) {
    
    
            System.out.printf("%d\tarr[%d]",i%maxSize,arr[i%maxSize]);
            System.out.println();
        }
        System.out.println();
    }
    public int check(){
    
    
        if(isEmpty()){
    
    
            throw  new RuntimeException("队列为空");
        }
        return arr[front];
    }

}

A classe de fila Queue em JAVA

Nos tipos de dados avançados de Java, a classe LinkedList implementa a interface Queue, para que possamos usar LinkedList como uma Fila.
LinkedList complementará a análise do código-fonte no capítulo sobre estrutura de dados de lista duplamente vinculada.

public class javaQueue {
    
    
    public  static void main(String args[]){
    
    
        //add()和remove()方法在失败的时候会抛出异常(不推荐)
        Queue<String> queue = new LinkedList<String>();
        //添加元素
        queue.offer("a");
        queue.offer("b");
        queue.offer("c");
        queue.offer("d");
        queue.offer("e");
        for(String q : queue){
    
    
            System.out.println(q);
        }
        System.out.println("===");
        System.out.println("poll="+queue.poll()); //返回第一个元素,并在队列中删除
        for(String q : queue){
    
    
            System.out.println(q);
        }
        System.out.println("===");
        System.out.println("element="+queue.element()); //返回第一个元素
        for(String q : queue){
    
    
            System.out.println(q);
        }
        System.out.println("===");
        System.out.println("peek="+queue.peek()); //返回第一个元素
        for(String q : queue){
    
    
            System.out.println(q);
        }
    }
}

A diferença entre oferecer e adicionar:

  • Algumas filas têm limites de tamanho, portanto, se você quiser adicionar um novo item a uma fila cheia, o item extra será rejeitado.
  • Neste momento, o novo método de oferta pode funcionar. Ele não lança uma exceção não verificada para chamar o método add (), mas apenas obtém o falso retornado por offer ().
    A diferença entre poll e remove:
  • Os métodos remove () e poll () removem o primeiro elemento da fila. O comportamento de remove () é semelhante à versão da interface Collection, mas o novo método poll () não lança uma exceção quando chamado com uma coleção vazia, mas retorna null. Portanto, o novo método é mais adequado para situações propensas a condições anormais.
    A diferença entre peek e element:
  • element () e peek () são usados ​​para consultar os elementos no início da fila. Semelhante ao método remove (), quando a fila está vazia, element () lança uma exceção e peek () retorna null.

Acho que você gosta

Origin blog.csdn.net/weixin_44634197/article/details/108308221
Recomendado
Clasificación