cola de implementación de matriz java (cola unidireccional y cola circular)

Título 1: El concepto de cola

Una cola es una lista ordenada y pertenece a una estructura lineal, que se puede implementar como una matriz o una lista vinculada.
Principio: Primero en
entrar , primero en salir Cola unidireccional: Solo se puede poner o quitar de
cola un extremo Cola circular: Se pueden implementar ambos extremos.

Título 2: Funcionamiento de la cola unidireccional

Idea: Primero declare la matriz, maxSize es el índice de la capacidad máxima de la cola, es decir, maxSize-1, porque el subíndice de la matriz comienza desde 0. Después de las colas posterior y frontal, el valor inicial es -1, posterior Cambia con la entrada de datos y el frente cambia con la salida de datos. Puedes entenderlo mirando la imagen.
Inserte la descripción de la imagen aquí
Analice las condiciones de que la cola esté llena y vacía:
llena: obviamente cuando trasera = MaxSize-1 está llena
Vacío: trasera = delantera está vacía
Analicemos el 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 程序返回,不再执行下面的代码(结束当前的方法 直接返回)
 */

¡Creo que los hermanos pueden entenderlo!

Título 3: Funcionamiento de la cola circular (es necesario comprender)

El frente apunta al primer elemento de la cola, y el trasero apunta al segundo bit después del último elemento, y ambos tienen un valor inicial de 0. Piense detenidamente en la diferencia con la cola unidireccional.
Principio de cola circular: De hecho, no hay circular en la memoria, por lo que la cola circular se realiza en el espacio lineal de la matriz.
Cuando la parte trasera vuelve a la posición 0, la operación de retroceso se realiza en módulo, es decir, la alineación circular se realiza en módulo.
Primero, hablemos de módulo: por ejemplo, si cualquier número% 8, el resultado después del módulo está entre 0 y 8.
El equipo está lleno: Su expresión es (trasero + 1)% maxSize = front.
Eche un vistazo a mi análisis: cuando trasero <maxSize-1, ¡el módulo no se da por nada! ! !
Haz un dibujo para entender que
Inserte la descripción de la imagen aquíquieres que d se una al equipo en este momento, él es el último elemento, cierto, entonces, ¿cuál es el valor de la parte trasera + 1? Se desborda, excede el tamaño de la matriz, pero en este momento nuestra cola no está llena y podemos insertarla antes. En este momento, podemos imaginar la matriz como un anillo, entonces el índice después de d es 0. Únase al equipo con una e, en la foto de arriba.

Inserte la descripción de la imagen aquíEn este momento, la parte trasera apunta a 1, entonces, ¿podemos agregar otros datos?

Si es posible, la parte trasera apuntará a 2, esta vez la parte trasera = delantera, y esta condición es precisamente la condición de que la cola esté vacía. Es lo mismo que la cola está llena. En este momento, es imposible juzgar si está vacía o llena. Por lo tanto, debemos dejar la última posición del último elemento como un acuerdo para no insertar datos, solo para juzgar si está vacío o lleno.
En este momento, la condición completa es (trasero + 1)% maxSize = front, y
esta expresión ya ha dejado un espacio para el acuerdo. Piense detenidamente y compare la imagen.
Al igual que cuando trasero = 1, maxSize = 6; trasero + 1 = 2% maxSize = 2% 6 = 2 = delantero. En este momento, la cola está llena y vacía. La posición apuntada por trasero es 1, y el índice anterior es El elemento de 0 es el último dato, el índice de 1 es la convención.
Un problema con la cola unidireccional es que cuando rear = maxSize, el programa pensará erróneamente que está lleno, por lo que no puede continuar insertándose. Esta cola unidireccional sólo se puede utilizar una vez.
La cola circular también resuelve este problema. En este momento, la capacidad de datos que la cola circular puede almacenar es maxSize,
pero ¿cuántos datos efectivos tiene?
¿Trasera delantera?
Esto debe estar mal porque se trata de un anillo, y la trasera puede ser más pequeña que la delantera. En este momento, ¡no lo des por nada! !
La expresión correcta (trasero-delantero + maxSize)% maxSize
explicado:
Mi propio entendimiento: trasero-delantero es la distancia entre la cabeza y el final del equipo. Los números negativos no se consideran, porque la distancia no puede ser negativa. Agregar maxSize y luego tomar el módulo no es un dato válido. Se puede entender en conjunto con la operación del módulo. En este momento, el módulo es quitar la distancia entre la cabeza y el final del equipo, lo cual no es válido.
En este momento, sabes que no puedes usar rear ++, solo toma el módulo.
En este momento trasero = (trasero + 1)% maxSize, delantero = (delantero + 1)% maxSize
pegue el siguiente código para entenderlo:

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];
    }
}

Comprensión personal, por favor ayúdame, sígueme o comenta, jajaja.

Supongo que te gusta

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