Implement queue (FIFO) using an array

Asked

Viewed 620 times

0

I have a fixed size 20 list, I need the user to add registrations, however, when I click on "show" option, it presents me only the first element I added in all positions. For example, if you type option 1 to insert and type 12, the entire array is occupied with number 12. How to solve?

public class Fifo {

    private int lista[];
    private int iniciolista;
    private int fimlista;
    private int matricula;
    private int i;





    //tem que criar as caracteristicas da classe fifo tipo oque ela é 
    Fifo(){
        lista = new int[20];
        iniciolista = -1;
        fimlista = -1;
    }

    public void adicionar (int matricula) {
            for (int i =0; i < lista.length; i++) {
            if (lista[i] == 0) {
            lista[i] = matricula;   
            }
        }
    }




    //mostrar o array
    public void mostrar () {
    for(int x = 0; x < lista.length; x++){
        System.out.println("posicao " + (x+1) + " = " +lista[x] );
    }
}

}
import javax.swing.JOptionPane;

public class MenuFifo {

    public static void main(String[] args) {
        int opcao, aux;
        String entra;
        int matricula;
        aux = 0;



        Fifo lista;
        lista = new Fifo();



        //A baixo a variavel "entra" ira receber o valor opcao para o usuario escolher que operação deseja fazer.
        do {
            entra = JOptionPane.showInputDialog("\n\n\nMENU DE OPCOES"
                    +"\n\n\t1. INSERIR\n\t2. RETIRAR\n\t3. MOSTRAR"
                    +"\n\t4. DETONAR\n\t5. CABECA\n\t6. POPULACAO"
                    +"\n\t7. VAGAS\n\t8. PROCURAR\n\t9. VAZAR");

            opcao = Integer.parseInt(entra);


        switch(opcao){


        //inserir a matricula na lista
        case 1:

        if (aux < 20) { 
            entra = JOptionPane.showInputDialog("INSIRA O NÚMERO DA MATRÍCULA\n");
            matricula = Integer.parseInt(entra);
            lista.adicionar(matricula);
            System.out.println("/nA matricula de numero "+matricula+" foi adicionada com sucesson/n");
            aux ++;
        } else {
            System.out.println("Você ultrapassou o limite da lista");
        }
        break;
        case 2:


            break;

        case 3:
            //mostrar o array 
            lista.mostrar();
            break;
        case 4:


            break;

        case 5:


            break;


        case 6:


            break;


        case 7: 

            break;


        case 8:


            break;
                }
            } while (opcao != 9);
        }
    }   

  • if you look closely your add method will see that it is going through the Dexes of your list, but if only allows you to add if it is at 0, then anything you add is always staying at index 0

1 answer

1


If we look at the language specification, we will see that an array of int is initialized with all its values equal to zero. So if I have this:

public class Fifo {

    private int lista[];

    public Fifo() {
        this.lista = new int[20];
    }

    public void mostrar() {
        for (int i = 0; i < lista.length; i++) {
            System.out.println(lista[i]);
        }
    }
}

...
public static void main(String[] args) {
    new Fifo().mostrar();
}

The program will print twenty times the number 0. Now back to your code (and I arranged the indentation to make it more readable):

public void adicionar(int matricula) {
    for (int i = 0; i < lista.length; i++) {
        if (lista[i] == 0) {
            lista[i] = matricula;
        }
    }
}

What it does is scroll through the entire list, and if the element is zero, it updates the value to matricula. But since all elements are zero, then all elements will be updated to matricula.


If you want to implement a queue (FIFO - First In, First Out), it makes no sense to go through the list all looking for elements that have a certain value. Note that you have variables to save the beginning and end of the queue, so use them. Of course using an array is not the best way to do this, but anyway, it would look something like this:

public class Fifo {
    private int lista[];
    private int inicio;
    private int fim;
    private boolean vazia;

    public Fifo() {
        this.lista = new int[20];
        this.inicio = 0;
        this.fim = 0;
        this.vazia = true;
    }

    public boolean isCheia() {
        return this.inicio == this.fim && !this.vazia;
    }

    public void adicionar(int valor) {
        if (isCheia()) {
            throw new IllegalStateException("Fila cheia");
        }
        this.lista[this.fim] = valor;
        this.fim = (this.fim + 1) % this.lista.length;
        this.vazia = false;
    }

    public int remover() {
        if (this.vazia) {
            throw new IllegalStateException("Fila vazia");
        }
        int valor = this.lista[inicio];
        this.inicio = (this.inicio + 1) % this.lista.length;
        this.vazia = this.inicio == this.fim;
        return valor;
    }

    public void mostrar() {
        int inicio = this.inicio;
        if (this.isCheia()) {
            System.out.println(this.lista[this.inicio]);
            inicio++;
        }
        for (int i = inicio; i != this.fim; i = (i + 1) % this.lista.length) {
            System.out.println(this.lista[i]);
        }
    }

    public int getTamanho() {
        System.out.println(this.inicio + ", " + this.fim);
        if (this.vazia)
            return 0;
        if (this.isCheia())
            return this.lista.length;
        if (this.fim > this.inicio)
            return this.fim - this.inicio;

        return this.fim + this.lista.length - this.inicio;
    }
}

I changed the names inicioLista and fimLista because it seems redundant to me to indicate that they are the beginning and end of the list. If these fields belong to the class Fifo, then obviously they represent the beginning and end of it, so I left the names simply as inicio and fim.

I removed the variable i because it makes no sense that she is part of the queue (she is not even being used, by the way, the i that has in the for is another variable, which exists only in that scope), and matricula was also removed because a queue will have multiple registrations, I did not understand why each queue should have an associated number plate.

In the method that adds I update only the final index, because in a queue (Fifo), the elements are added at the end. To increase the index, I use % which is the rest of the division, so I guarantee that the index does not exceed the size of the array (if I am at the last index, it goes back to the beginning of the array).

The same goes for the method that removes, but in this I update the initial index. To print, I show only the elements that have been added. There is no need to go through the entire array if not all elements are part of the queue.

Note that there are some adjustments for when the list is full. This is because I am using the array in a "circular" way, that is, the indexes are being incremented, but if they reach the end of the array, they go back to the beginning. So if I keep adding and removing several times, I might end up in a situation where the beginning is 10 and the end is 2, for example (so to scroll through the queue I should start at index 10, go to the end of the array and then go back at the beginning and go to index 2).

Because of this, both empty and full queue will have the initial and final indexes equal, so you have one more field to indicate if the queue is empty.

An example of use:

Fifo f = new Fifo();
f.mostrar();
f.adicionar(1);
f.adicionar(5);
f.adicionar(10);
f.mostrar();

System.out.println("Remover: " + f.remover());
f.mostrar();

Exit:

1
5
10
Remover: 1
5
10

If it’s not a drill and you need a line, use the already existing implementations:

import java.util.LinkedList;
import java.util.Queue;


Queue<Integer> fila = new LinkedList<Integer>();
fila.add(1);
fila.add(5);
fila.add(10);
for (int i : fila) {
    System.out.println(i);
}
System.out.println("Remover: " + fila.poll());
for (int i : fila) {
    System.out.println(i);
}

The output is the same as the previous code.

If you want to control the maximum queue size, use fila.size() to check (something like if (fila.size() == 20) { não pode mais adicionar }, etc.).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.